diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 839ca37981..bebb8da72c 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -341,12 +341,12 @@ of each style or click on the style itself for a full description: efieldenforce2devaporateexternalfreezegcmcgravityheat indentlangevinlineforcemomentummovemsstnebnph nphugnph/aspherenph/spherenptnpt/aspherenpt/spherenvenve/asphere -nve/limitnve/noforcenve/spherenvtnvt/aspherenvt/sllodnvt/sphereorient/fcc -planeforcepoemspourpress/berendsenprintqeq/combreax/bondsrecenter -restrainrigidrigid/nverigid/nvtsetforceshakespringspring/rg -spring/selfsrdstore/forcestore/statetemp/berendsentemp/rescalethermal/conductivitytmd -ttmviscosityviscouswall/colloidwall/granwall/harmonicwall/lj126wall/lj93 -wall/reflectwall/regionwall/srd +nve/limitnve/linenve/noforcenve/spherenve/trinvtnvt/aspherenvt/sllod +nvt/sphereorient/fccplaneforcepoemspourpress/berendsenprintqeq/comb +reax/bondsrecenterrestrainrigidrigid/nverigid/nvtsetforceshake +springspring/rgspring/selfsrdstore/forcestore/statetemp/berendsentemp/rescale +thermal/conductivitytmdttmviscosityviscouswall/colloidwall/granwall/harmonic +wall/lj126wall/lj93wall/reflectwall/regionwall/srd

These are fix styles contributed by users, which can be used if @@ -419,15 +419,15 @@ potentials. Click on the style itself for a full description: dpddpd/tstatdsmceam eam/alloyeam/fseimgauss gaybernegran/hertz/historygran/hookegran/hooke/history -hbond/dreiding/ljhbond/dreiding/morselj/charmm/coul/charmmlj/charmm/coul/charmm/implicit -lj/charmm/coul/longlj/class2lj/class2/coul/cutlj/class2/coul/long -lj/cutlj/cut/coul/cutlj/cut/coul/debyelj/cut/coul/long -lj/cut/coul/long/tip4plj/expandlj/gromacslj/gromacs/coul/gromacs -lj/smoothlj96/cutlubricatemeam -morseperi/lpsperi/pmbreax -reboresquaredsoftsw -tabletersofftersoff/zblyukawa -yukawa/colloid +hbond/dreiding/ljhbond/dreiding/morseline/ljlj/charmm/coul/charmm +lj/charmm/coul/charmm/implicitlj/charmm/coul/longlj/class2lj/class2/coul/cut +lj/class2/coul/longlj/cutlj/cut/coul/cutlj/cut/coul/debye +lj/cut/coul/longlj/cut/coul/long/tip4plj/expandlj/gromacs +lj/gromacs/coul/gromacslj/smoothlj96/cutlubricate +meammorseperi/lpsperi/pmb +reaxreboresquaredsoft +swtabletersofftersoff/zbl +tri/ljyukawayukawa/colloid

These are pair styles contributed by users, which can be used if @@ -473,8 +473,9 @@ package. lj96/cut/cudalj96/cut/gpulj96/cut/omplubricate/omp morse/cudamorse/gpumorse/ompmorse/opt peri/lps/ompperi/pmb/omprebo/ompresquared/gpu resquared/omp -soft/ompsw/omptable/omptersoff/omp -tersoff/zbl/ompyukawa/ompyukawa/colloid/omp +soft/ompsw/cudasw/omptable/omp +tersoff/cudatersoff/omptersoff/zbl/ompyukawa/omp +yukawa/colloid/omp


diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index c3677b939b..517791a061 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -438,8 +438,10 @@ of each style or click on the style itself for a full description: "nve"_fix_nve.html, "nve/asphere"_fix_nve_asphere.html, "nve/limit"_fix_nve_limit.html, +"nve/line"_fix_nve_line.html, "nve/noforce"_fix_nve_noforce.html, "nve/sphere"_fix_nve_sphere.html, +"nve/tri"_fix_nve_tri.html, "nvt"_fix_nh.html, "nvt/asphere"_fix_nvt_asphere.html, "nvt/sllod"_fix_nvt_sllod.html, @@ -638,6 +640,7 @@ potentials. Click on the style itself for a full description: "gran/hooke/history"_pair_gran.html, "hbond/dreiding/lj"_pair_hbond_dreiding.html, "hbond/dreiding/morse"_pair_hbond_dreiding.html, +"line/lj"_pair_line_lj.html, "lj/charmm/coul/charmm"_pair_charmm.html, "lj/charmm/coul/charmm/implicit"_pair_charmm.html, "lj/charmm/coul/long"_pair_charmm.html, @@ -667,6 +670,7 @@ potentials. Click on the style itself for a full description: "table"_pair_table.html, "tersoff"_pair_tersoff.html, "tersoff/zbl"_pair_tersoff_zbl.html, +"tri/lj"_pair_tri_lj.html, "yukawa"_pair_yukawa.html, "yukawa/colloid"_pair_yukawa_colloid.html :tb(c=4,ea=c) @@ -803,8 +807,10 @@ package"_Section_accelerate.html. "resquared/gpu"_pair_resquared.html, "resquared/omp"_pair_resquared.html, "soft/omp"_pair_soft.html, +"sw/cuda"_pair_sw.html, "sw/omp"_pair_sw.html, "table/omp"_pair_table.html, +"tersoff/cuda"_pair_tersoff.html, "tersoff/omp"_pair_tersoff.html, "tersoff/zbl/omp"_pair_tersoff_zbl.html, "yukawa/omp"_pair_yukawa.html, diff --git a/doc/Section_intro.html b/doc/Section_intro.html index bced87e8c1..3b659cf8e7 100644 --- a/doc/Section_intro.html +++ b/doc/Section_intro.html @@ -125,7 +125,8 @@ LAMMPS.
  • metals
  • granular materials
  • coarse-grained mesoscale models -
  • extended spherical and ellipsoidal particles +
  • finite-size spherical and ellipsoidal particles +
  • finite-size line segment (2d) and triangle (3d) particles
  • point dipolar particles
  • rigid collections of particles
  • hybrid combinations of these diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt index 95a934830a..2ceb4f78d4 100644 --- a/doc/Section_intro.txt +++ b/doc/Section_intro.txt @@ -121,7 +121,8 @@ Particle and model types :h4 metals granular materials coarse-grained mesoscale models - extended spherical and ellipsoidal particles + finite-size spherical and ellipsoidal particles + finite-size line segment (2d) and triangle (3d) particles point dipolar particles rigid collections of particles hybrid combinations of these :ul diff --git a/doc/Section_modify.html b/doc/Section_modify.html index 8a85bd0c39..8e217b40fe 100644 --- a/doc/Section_modify.html +++ b/doc/Section_modify.html @@ -142,44 +142,49 @@ features that can be added in the manner just described:

    10.1 Atom styles

    -

    Classes that define an atom style are derived from the Atom class. -The atom style determines what quantities are associated with an atom. -A new atom style can be created if one of the existing atom styles -does not define all the arrays you need to store and communicate with -atoms. +

    Classes that define an atom style are derived from the AtomVec class +and managed by the Atom class. The atom style determines what +quantities are associated with an atom. A new atom style can be +created if one of the existing atom styles does not define all +the arrays you need to store and communicate with atoms.

    Atom_vec_atomic.cpp is a simple example of an atom style.

    Here is a brief description of methods you define in your new derived -class. See atom.h for details. +class. See atom_vec.h for details.

    - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    grow re-allocate atom arrays to longer lengths
    copy copy info for one atom to another atom's array locations
    pack_comm store an atom's info in a buffer communicated every timestep
    pack_comm_vel add velocity info to buffer
    pack_comm_one store extra info unique to this atom style
    unpack_comm retrieve an atom's info from the buffer
    unpack_comm_vel also retrieve velocity info
    unpack_comm_one retreive extra info unique to this atom style
    pack_reverse store an atom's info in a buffer communicating partial forces
    pack_reverse_one store extra info unique to this atom style
    unpack_reverse retrieve an atom's info from the buffer
    unpack_reverse_one retreive extra info unique to this atom style
    pack_border store an atom's info in a buffer communicated on neighbor re-builds
    pack_border_vel add velocity info to buffer
    pack_border_one store extra info unique to this atom style
    unpack_border retrieve an atom's info from the buffer
    unpack_border_vel also retrieve velocity info
    unpack_border_one retreive extra info unique to this atom style
    pack_exchange store all an atom's info to migrate to another processor
    unpack_exchange retrieve an atom's info from the buffer
    size_restart number of restart quantities associated with proc's atoms
    pack_restart pack atom quantities into a buffer
    unpack_restart unpack atom quantities from a buffer
    create_atom create an individual atom of this style
    data_atom parse an atom line from the data file
    memory_usage tally memory allocated by atom arrays +
    init one time setup (optional)
    grow re-allocate atom arrays to longer lengths (required)
    grow_reset make array pointers in Atom and AtomVec classes consistent (required)
    copy copy info for one atom to another atom's array locations (required)
    pack_comm store an atom's info in a buffer communicated every timestep (required)
    pack_comm_vel add velocity info to communication buffer (required)
    pack_comm_hybrid store extra info unique to this atom style (optional)
    unpack_comm retrieve an atom's info from the buffer (required)
    unpack_comm_vel also retrieve velocity info (required)
    unpack_comm_hybrid retreive extra info unique to this atom style (optional)
    pack_reverse store an atom's info in a buffer communicating partial forces (required)
    pack_reverse_hybrid store extra info unique to this atom style (optional)
    unpack_reverse retrieve an atom's info from the buffer (required)
    unpack_reverse_hybrid retreive extra info unique to this atom style (optional)
    pack_border store an atom's info in a buffer communicated on neighbor re-builds (required)
    pack_border_vel add velocity info to buffer (required)
    pack_border_hybrid store extra info unique to this atom style (optional)
    unpack_border retrieve an atom's info from the buffer (required)
    unpack_border_vel also retrieve velocity info (required)
    unpack_border_hybrid retreive extra info unique to this atom style (optional)
    pack_exchange store all an atom's info to migrate to another processor (required)
    unpack_exchange retrieve an atom's info from the buffer (required)
    size_restart number of restart quantities associated with proc's atoms (required)
    pack_restart pack atom quantities into a buffer (required)
    unpack_restart unpack atom quantities from a buffer (required)
    create_atom create an individual atom of this style (required)
    data_atom parse an atom line from the data file (required)
    data_atom_hybrid parse additional atom info unique to this atom style (optional)
    data_vel parse one line of velocity information from data file (optional)
    data_vel_hybrid parse additional velocity data unique to this atom style (optional)
    memory_usage tally memory allocated by atom arrays (required)

    The constructor of the derived class sets values for several variables @@ -200,16 +205,21 @@ add new potentials to LAMMPS. the harmonic forms of the angle, dihedral, and improper style commands.

    -

    Here is a brief description of methods you define in your new derived -bond class. See bond.h, angle.h, dihedral.h, and improper.h for -details. +

    Here is a brief description of common methods you define in your +new derived class. See bond.h, angle.h, dihedral.h, and improper.h +for details and specific additional methods.

    - - - - - + + + + + + + + +
    compute compute the molecular interactions
    coeff set coefficients for one bond type
    equilibrium_distance length of bond, used by SHAKE
    write & read_restart writes/reads coeffs to restart files
    single force and energy of a single bond +
    init check if all coefficients are set, calls init_style (optional)
    init_style check if style specific conditions are met (optional)
    compute compute the molecular interactions (required)
    settings apply global settings for all types (optional)
    coeff set coefficients for one type (required)
    equilibrium_distance length of bond, used by SHAKE (required, bond only)
    equilibrium_angle opening of angle, used by SHAKE (required, angle only)
    write & read_restart writes/reads coeffs to restart files (required)
    single force and energy of a single bond or angle (required, bond or angle only)
    memory_usage tally memory allocated by the style (optional)

    @@ -230,14 +240,21 @@ per-atom kinetic energy. class. See compute.h for details.

    - - - - - - - - + + + + + + + + + + + + + +
    compute_scalar compute a scalar quantity
    compute_vector compute a vector of quantities
    compute_peratom compute one or more quantities per atom
    pack_comm pack a buffer with items to communicate
    unpack_comm unpack the buffer
    pack_reverse pack a buffer with items to reverse communicate
    unpack_reverse unpack the buffer
    memory_usage tally memory usage +
    init perform one time setup (required)
    init_list neighbor list setup, if needed (optional)
    compute_scalar compute a scalar quantity (optional)
    compute_vector compute a vector of quantities (optional)
    compute_peratom compute one or more quantities per atom (optional)
    compute_local compute one or more quantities per processor (optional)
    pack_comm pack a buffer with items to communicate (optional)
    unpack_comm unpack the buffer (optional)
    pack_reverse pack a buffer with items to reverse communicate (optional)
    unpack_reverse unpack the buffer (optional)
    remove_bias remove velocity bias from one atom (optional)
    remove_bias_all remove velocity bias from all atoms in group (optional)
    restore_bias restore velocity bias for one atom after remove_bias (optional)
    restore_bias_all same as before, but for all atoms in group (optional)
    memory_usage tally memory usage (optional)

    @@ -295,34 +312,59 @@ implement. derived class. See fix.h for details.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    setmask determines when the fix is called during the timestep
    init initialization before a run
    setup called immediately before the 1st timestep
    initial_integrate called at very beginning of each timestep
    pre_exchange called before atom exchange on re-neighboring steps
    pre_neighbor called before neighbor list build
    post_force called after pair & molecular forces are computed
    final_integrate called at end of each timestep
    end_of_step called at very end of timestep
    write_restart dumps fix info to restart file
    restart uses info from restart file to re-initialize the fix
    grow_arrays allocate memory for atom-based arrays used by fix
    copy_arrays copy atom info when an atom migrates to a new processor
    memory_usage report memory used by fix
    pack_exchange store atom's data in a buffer
    unpack_exchange retrieve atom's data from a buffer
    pack_restart store atom's data for writing to restart file
    unpack_restart retrieve atom's data from a restart file buffer
    size_restart size of atom's data
    maxsize_restart max size of atom's data
    initial_integrate_respa same as initial_integrate, but for rRESPA
    post_force_respa same as post_force, but for rRESPA
    final_integrate_respa same as final_integrate, but for rRESPA
    pack_comm pack a buffer to communicate a per-atom quantity
    unpack_comm unpack a buffer to communicate a per-atom quantity
    pack_reverse_comm pack a buffer to reverse communicate a per-atom quantity
    unpack_reverse_comm unpack a buffer to reverse communicate a per-atom quantity
    thermo compute quantities for thermodynamic output +
    setmask determines when the fix is called during the timestep (required)
    init initialization before a run (optional)
    setup_pre_exchange called before atom exchange in setup (optional)
    setup_pre_force called before force computation in setup (optional)
    setup called immediately before the 1st timestep and after forces are computed (optional)
    min_setup_pre_force like setup_pre_force, but for minimizations instead of MD runs (optional)
    min_setup like setup, but for minimizations instead of MD runs (optional)
    initial_integrate called at very beginning of each timestep (optional)
    pre_exchange called before atom exchange on re-neighboring steps (optional)
    pre_neighbor called before neighbor list build (optional)
    pre_force called after pair & molecular forces are computed (optional)
    post_force called after pair & molecular forces are computed and communicated (optional)
    final_integrate called at end of each timestep (optional)
    end_of_step called at very end of timestep (optional)
    write_restart dumps fix info to restart file (optional)
    restart uses info from restart file to re-initialize the fix (optional)
    grow_arrays allocate memory for atom-based arrays used by fix (optional)
    copy_arrays copy atom info when an atom migrates to a new processor (optional)
    pack_exchange store atom's data in a buffer (optional)
    unpack_exchange retrieve atom's data from a buffer (optional)
    pack_restart store atom's data for writing to restart file (optional)
    unpack_restart retrieve atom's data from a restart file buffer (optional)
    size_restart size of atom's data (optional)
    maxsize_restart max size of atom's data (optional)
    setup_pre_force_respa same as setup_pre_force, but for rRESPA (optional)
    initial_integrate_respa same as initial_integrate, but for rRESPA (optional)
    post_integrate_respa called after the first half integration step is done in rRESPA (optional)
    pre_force_respa same as pre_force, but for rRESPA (optional)
    post_force_respa same as post_force, but for rRESPA (optional)
    final_integrate_respa same as final_integrate, but for rRESPA (optional)
    min_pre_force called after pair & molecular forces are computed in minimizer (optional)
    min_post_force called after pair & molecular forces are computed and communicated in minmizer (optional)
    min_store store extra data for linesearch based minimization on a LIFO stack (optional)
    min_pushstore push the minimization LIFO stack one element down (optional)
    min_popstore pop the minimization LIFO stack one element up (optional)
    min_clearstore clear minimization LIFO stack (optional)
    min_step reset or move forward on line search minimization (optional)
    min_dof report number of degrees of freedom added by this fix in minimization (optional)
    max_alpha report maximum allowed step size during linesearch minimization (optional)
    pack_comm pack a buffer to communicate a per-atom quantity (optional)
    unpack_comm unpack a buffer to communicate a per-atom quantity (optional)
    pack_reverse_comm pack a buffer to reverse communicate a per-atom quantity (optional)
    unpack_reverse_comm unpack a buffer to reverse communicate a per-atom quantity (optional)
    dof report number of degrees of freedom removed by this fix during MD (optional)
    compute_scalar return a global scalar property that the fix computes (optional)
    compute_vector return a component of a vector property that the fix computes (optional)
    compute_array return a component of an array property that the fix computes (optional)
    deform called when the box size is changed (optional)
    reset_target called when a change of the target temperature is requested during a run (optional)
    reset_dt is called when a change of the time step is requested during a run (optional)
    modify_param called when a fix_modify request is executed (optional)
    memory_usage report memory used by fix (optional)
    thermo compute quantities for thermodynamic output (optional)

    Typically, only a small fraction of these methods are defined for a diff --git a/doc/Section_modify.txt b/doc/Section_modify.txt index 662a1729a8..789761cbb2 100644 --- a/doc/Section_modify.txt +++ b/doc/Section_modify.txt @@ -140,43 +140,48 @@ features that can be added in the manner just described: 10.1 Atom styles :link(mod_1),h4 -Classes that define an atom style are derived from the Atom class. -The atom style determines what quantities are associated with an atom. -A new atom style can be created if one of the existing atom styles -does not define all the arrays you need to store and communicate with -atoms. +Classes that define an atom style are derived from the AtomVec class +and managed by the Atom class. The atom style determines what +quantities are associated with an atom. A new atom style can be +created if one of the existing atom styles does not define all +the arrays you need to store and communicate with atoms. Atom_vec_atomic.cpp is a simple example of an atom style. Here is a brief description of methods you define in your new derived -class. See atom.h for details. +class. See atom_vec.h for details. -grow: re-allocate atom arrays to longer lengths -copy: copy info for one atom to another atom's array locations -pack_comm: store an atom's info in a buffer communicated every timestep -pack_comm_vel: add velocity info to buffer -pack_comm_one: store extra info unique to this atom style -unpack_comm: retrieve an atom's info from the buffer -unpack_comm_vel: also retrieve velocity info -unpack_comm_one: retreive extra info unique to this atom style -pack_reverse: store an atom's info in a buffer communicating partial forces -pack_reverse_one: store extra info unique to this atom style -unpack_reverse: retrieve an atom's info from the buffer -unpack_reverse_one: retreive extra info unique to this atom style -pack_border: store an atom's info in a buffer communicated on neighbor re-builds -pack_border_vel: add velocity info to buffer -pack_border_one: store extra info unique to this atom style -unpack_border: retrieve an atom's info from the buffer -unpack_border_vel: also retrieve velocity info -unpack_border_one: retreive extra info unique to this atom style -pack_exchange: store all an atom's info to migrate to another processor -unpack_exchange: retrieve an atom's info from the buffer -size_restart: number of restart quantities associated with proc's atoms -pack_restart: pack atom quantities into a buffer -unpack_restart: unpack atom quantities from a buffer -create_atom: create an individual atom of this style -data_atom: parse an atom line from the data file -memory_usage: tally memory allocated by atom arrays :tb(s=:) +init: one time setup (optional) +grow: re-allocate atom arrays to longer lengths (required) +grow_reset: make array pointers in Atom and AtomVec classes consistent (required) +copy: copy info for one atom to another atom's array locations (required) +pack_comm: store an atom's info in a buffer communicated every timestep (required) +pack_comm_vel: add velocity info to communication buffer (required) +pack_comm_hybrid: store extra info unique to this atom style (optional) +unpack_comm: retrieve an atom's info from the buffer (required) +unpack_comm_vel: also retrieve velocity info (required) +unpack_comm_hybrid: retreive extra info unique to this atom style (optional) +pack_reverse: store an atom's info in a buffer communicating partial forces (required) +pack_reverse_hybrid: store extra info unique to this atom style (optional) +unpack_reverse: retrieve an atom's info from the buffer (required) +unpack_reverse_hybrid: retreive extra info unique to this atom style (optional) +pack_border: store an atom's info in a buffer communicated on neighbor re-builds (required) +pack_border_vel: add velocity info to buffer (required) +pack_border_hybrid: store extra info unique to this atom style (optional) +unpack_border: retrieve an atom's info from the buffer (required) +unpack_border_vel: also retrieve velocity info (required) +unpack_border_hybrid: retreive extra info unique to this atom style (optional) +pack_exchange: store all an atom's info to migrate to another processor (required) +unpack_exchange: retrieve an atom's info from the buffer (required) +size_restart: number of restart quantities associated with proc's atoms (required) +pack_restart: pack atom quantities into a buffer (required) +unpack_restart: unpack atom quantities from a buffer (required) +create_atom: create an individual atom of this style (required) +data_atom: parse an atom line from the data file (required) +data_atom_hybrid: parse additional atom info unique to this atom style (optional) +data_vel: parse one line of velocity information from data file (optional) +data_vel_hybrid: parse additional velocity data unique to this atom style (optional) +memory_usage: tally memory allocated by atom arrays (required) :tb(s=:) The constructor of the derived class sets values for several variables that you must set when defining a new atom style, which are documented @@ -196,15 +201,20 @@ Bond_harmonic.cpp is the simplest example of a bond style. Ditto for the harmonic forms of the angle, dihedral, and improper style commands. -Here is a brief description of methods you define in your new derived -bond class. See bond.h, angle.h, dihedral.h, and improper.h for -details. +Here is a brief description of common methods you define in your +new derived class. See bond.h, angle.h, dihedral.h, and improper.h +for details and specific additional methods. -compute: compute the molecular interactions -coeff: set coefficients for one bond type -equilibrium_distance: length of bond, used by SHAKE -write & read_restart: writes/reads coeffs to restart files -single: force and energy of a single bond :tb(s=:) +init: check if all coefficients are set, calls {init_style} (optional) +init_style: check if style specific conditions are met (optional) +compute: compute the molecular interactions (required) +settings: apply global settings for all types (optional) +coeff: set coefficients for one type (required) +equilibrium_distance: length of bond, used by SHAKE (required, bond only) +equilibrium_angle: opening of angle, used by SHAKE (required, angle only) +write & read_restart: writes/reads coeffs to restart files (required) +single: force and energy of a single bond or angle (required, bond or angle only) +memory_usage: tally memory allocated by the style (optional) :tb(s=:) :line @@ -223,14 +233,21 @@ per-atom kinetic energy. Here is a brief description of methods you define in your new derived class. See compute.h for details. -compute_scalar: compute a scalar quantity -compute_vector: compute a vector of quantities -compute_peratom: compute one or more quantities per atom -pack_comm: pack a buffer with items to communicate -unpack_comm: unpack the buffer -pack_reverse: pack a buffer with items to reverse communicate -unpack_reverse: unpack the buffer -memory_usage: tally memory usage :tb(s=:) +init: perform one time setup (required) +init_list: neighbor list setup, if needed (optional) +compute_scalar: compute a scalar quantity (optional) +compute_vector: compute a vector of quantities (optional) +compute_peratom: compute one or more quantities per atom (optional) +compute_local: compute one or more quantities per processor (optional) +pack_comm: pack a buffer with items to communicate (optional) +unpack_comm: unpack the buffer (optional) +pack_reverse: pack a buffer with items to reverse communicate (optional) +unpack_reverse: unpack the buffer (optional) +remove_bias: remove velocity bias from one atom (optional) +remove_bias_all: remove velocity bias from all atoms in group (optional) +restore_bias: restore velocity bias for one atom after remove_bias (optional) +restore_bias_all: same as before, but for all atoms in group (optional) +memory_usage: tally memory usage (optional) :tb(s=:) :line @@ -283,34 +300,59 @@ implement. Here is a brief description of methods you can define in your new derived class. See fix.h for details. -setmask: determines when the fix is called during the timestep -init: initialization before a run -setup: called immediately before the 1st timestep -initial_integrate: called at very beginning of each timestep -pre_exchange: called before atom exchange on re-neighboring steps -pre_neighbor: called before neighbor list build -post_force: called after pair & molecular forces are computed -final_integrate: called at end of each timestep -end_of_step: called at very end of timestep -write_restart: dumps fix info to restart file -restart: uses info from restart file to re-initialize the fix -grow_arrays: allocate memory for atom-based arrays used by fix -copy_arrays: copy atom info when an atom migrates to a new processor -memory_usage: report memory used by fix -pack_exchange: store atom's data in a buffer -unpack_exchange: retrieve atom's data from a buffer -pack_restart: store atom's data for writing to restart file -unpack_restart: retrieve atom's data from a restart file buffer -size_restart: size of atom's data -maxsize_restart: max size of atom's data -initial_integrate_respa: same as initial_integrate, but for rRESPA -post_force_respa: same as post_force, but for rRESPA -final_integrate_respa: same as final_integrate, but for rRESPA -pack_comm: pack a buffer to communicate a per-atom quantity -unpack_comm: unpack a buffer to communicate a per-atom quantity -pack_reverse_comm: pack a buffer to reverse communicate a per-atom quantity -unpack_reverse_comm: unpack a buffer to reverse communicate a per-atom quantity -thermo: compute quantities for thermodynamic output :tb(s=:) +setmask: determines when the fix is called during the timestep (required) +init: initialization before a run (optional) +setup_pre_exchange: called before atom exchange in setup (optional) +setup_pre_force: called before force computation in setup (optional) +setup: called immediately before the 1st timestep and after forces are computed (optional) +min_setup_pre_force: like setup_pre_force, but for minimizations instead of MD runs (optional) +min_setup: like setup, but for minimizations instead of MD runs (optional) +initial_integrate: called at very beginning of each timestep (optional) +pre_exchange: called before atom exchange on re-neighboring steps (optional) +pre_neighbor: called before neighbor list build (optional) +pre_force: called after pair & molecular forces are computed (optional) +post_force: called after pair & molecular forces are computed and communicated (optional) +final_integrate: called at end of each timestep (optional) +end_of_step: called at very end of timestep (optional) +write_restart: dumps fix info to restart file (optional) +restart: uses info from restart file to re-initialize the fix (optional) +grow_arrays: allocate memory for atom-based arrays used by fix (optional) +copy_arrays: copy atom info when an atom migrates to a new processor (optional) +pack_exchange: store atom's data in a buffer (optional) +unpack_exchange: retrieve atom's data from a buffer (optional) +pack_restart: store atom's data for writing to restart file (optional) +unpack_restart: retrieve atom's data from a restart file buffer (optional) +size_restart: size of atom's data (optional) +maxsize_restart: max size of atom's data (optional) +setup_pre_force_respa: same as setup_pre_force, but for rRESPA (optional) +initial_integrate_respa: same as initial_integrate, but for rRESPA (optional) +post_integrate_respa: called after the first half integration step is done in rRESPA (optional) +pre_force_respa: same as pre_force, but for rRESPA (optional) +post_force_respa: same as post_force, but for rRESPA (optional) +final_integrate_respa: same as final_integrate, but for rRESPA (optional) +min_pre_force: called after pair & molecular forces are computed in minimizer (optional) +min_post_force: called after pair & molecular forces are computed and communicated in minmizer (optional) +min_store: store extra data for linesearch based minimization on a LIFO stack (optional) +min_pushstore: push the minimization LIFO stack one element down (optional) +min_popstore: pop the minimization LIFO stack one element up (optional) +min_clearstore: clear minimization LIFO stack (optional) +min_step: reset or move forward on line search minimization (optional) +min_dof: report number of degrees of freedom {added} by this fix in minimization (optional) +max_alpha: report maximum allowed step size during linesearch minimization (optional) +pack_comm: pack a buffer to communicate a per-atom quantity (optional) +unpack_comm: unpack a buffer to communicate a per-atom quantity (optional) +pack_reverse_comm: pack a buffer to reverse communicate a per-atom quantity (optional) +unpack_reverse_comm: unpack a buffer to reverse communicate a per-atom quantity (optional) +dof: report number of degrees of freedom {removed} by this fix during MD (optional) +compute_scalar: return a global scalar property that the fix computes (optional) +compute_vector: return a component of a vector property that the fix computes (optional) +compute_array: return a component of an array property that the fix computes (optional) +deform: called when the box size is changed (optional) +reset_target: called when a change of the target temperature is requested during a run (optional) +reset_dt: is called when a change of the time step is requested during a run (optional) +modify_param: called when a fix_modify request is executed (optional) +memory_usage: report memory used by fix (optional) +thermo: compute quantities for thermodynamic output (optional) :tb(s=:) Typically, only a small fraction of these methods are defined for a particular fix. Setmask is mandatory, as it determines when the fix diff --git a/doc/Section_start.html b/doc/Section_start.html index bfe24d404e..438f879dd6 100644 --- a/doc/Section_start.html +++ b/doc/Section_start.html @@ -1016,6 +1016,12 @@ defining index and other kinds of variables and


    2.7 LAMMPS screen output diff --git a/doc/Section_start.txt b/doc/Section_start.txt index 5ae3fb715c..674dec45b7 100644 --- a/doc/Section_start.txt +++ b/doc/Section_start.txt @@ -1008,6 +1008,12 @@ defining index and other kinds of variables and "this section"_Section_commands.html#cmd_2 for more info on using variables in input scripts. +NOTE: Currently, the command-line parser looks for arguments that +start with "-" to indicate new switches. Thus you cannot specify +multiple variable values if any of they start with a "-", e.g. a +negative numeric value. It is OK if the first value1 starts with a +"-", since it is automatically skipped. + :line 2.7 LAMMPS screen output :h4,link(start_7) diff --git a/doc/atom_style.html b/doc/atom_style.html index 8356e44dfc..77ca19b72f 100644 --- a/doc/atom_style.html +++ b/doc/atom_style.html @@ -15,7 +15,7 @@

    atom_style style args 
     
    - @@ -79,12 +85,13 @@ additional quantities that are only defined for certain dump custom command are as follows. +

    The additional quantities only accessible via this command, and not +directly via the dump custom command, are as follows.

    Shapex, shapey, and shapez are defined for ellipsoidal particles and define the 3d shape of each particle. Quatw, quati, quatj, @@ -93,6 +100,13 @@ and quatk are also defined for ellipsoidal particles and store the See the set command for an explanation of the quaternion vector.

    +

    End1x, end1y, end1z, end2x, end2y, end2z, are defined for +line segment particles and define the end points of each line segment. +

    +

    Corner1x, corner1y, corner1z, corner2x, corner2y, +corner2z, corner3x, corner3y, corner3z, are defined for +triangular particles and define the corner points of each triangle. +

    Output info:

    This compute calculates a per-atom vector or per-atom array depending diff --git a/doc/compute_property_atom.txt b/doc/compute_property_atom.txt index bae2846f4e..500ca25df4 100644 --- a/doc/compute_property_atom.txt +++ b/doc/compute_property_atom.txt @@ -23,8 +23,11 @@ input = one or more atom attributes :l angmomx, angmomy, angmomz, shapex,shapey, shapez, quatw, quati, quatj, quatk, tqx, tqy, tqz, - spin, eradius, ervel, erforce :pre - + spin, eradius, ervel, erforce + end1x, end1y, end1z, end2x, end2y, end2z, + corner1x, corner1y, corner1z, + corner2x, corner2y, corner2z, + corner3x, corner3y, corner3z :pre id = atom ID mol = molecule ID type = atom type @@ -41,13 +44,15 @@ input = one or more atom attributes :l radius,diameter = radius,diameter of spherical particle omegax,omegay,omegaz = angular velocity of extended particle angmomx,angmomy,angmomz = angular momentum of extended particle + shapex,shapey,shapez = 3 diameters of aspherical particle + quatw,quati,quatj,quatk = quaternion components for aspherical particles tqx,tqy,tqz = torque on extended particles spin = electron spin eradius = electron radius ervel = electron radial velocity erforce = electron radial force - shapex,shapey,shapez = 3 diameters of aspherical particle - quatw,quati,quatj,quatk = quaternion components for aspherical particles :pre + end12x, end12y, end12z = end points of line segment + coner123x, corner123y, corner123z = corner points of triangle :pre :ule [Examples:] @@ -72,12 +77,13 @@ additional quantities that are only defined for certain "atom styles"_atom_style.html. Basically, this list gives your input script access to any per-atom quantity stored by LAMMPS. -The values are stored in a per-atom vector or array as -discussed below. Zeroes are stored for atoms not in the specified -group. +The values are stored in a per-atom vector or array as discussed +below. Zeroes are stored for atoms not in the specified group or for +quantities that are not defined for a particular particle in the group +(e.g. {shapex} if the particle is not an ellipsoid). -The additional quantities only accessible via this command (and not -directly via the "dump custom"_dump.html command are as follows. +The additional quantities only accessible via this command, and not +directly via the "dump custom"_dump.html command, are as follows. {Shapex}, {shapey}, and {shapez} are defined for ellipsoidal particles and define the 3d shape of each particle. {Quatw}, {quati}, {quatj}, @@ -86,6 +92,13 @@ and {quatk} are also defined for ellipsoidal particles and store the See the "set"_set.html command for an explanation of the quaternion vector. +{End1x}, {end1y}, {end1z}, {end2x}, {end2y}, {end2z}, are defined for +line segment particles and define the end points of each line segment. + +{Corner1x}, {corner1y}, {corner1z}, {corner2x}, {corner2y}, +{corner2z}, {corner3x}, {corner3y}, {corner3z}, are defined for +triangular particles and define the corner points of each triangle. + [Output info:] This compute calculates a per-atom vector or per-atom array depending diff --git a/doc/fix.html b/doc/fix.html index e73695d95e..6d84638722 100644 --- a/doc/fix.html +++ b/doc/fix.html @@ -200,8 +200,10 @@ list of fix styles available in LAMMPS:

  • nve - constant NVE time integration
  • nve/asphere - NVT for aspherical particles
  • nve/limit - NVE with limited step length +
  • nve/line - NVE for line segments
  • nve/noforce - NVE without forces (v only)
  • nve/sphere - NVT for spherical particles +
  • nve/tri - NVE for triangles
  • nvt - constant NVT time integration via Nose/Hoover
  • nvt/asphere - NVT for aspherical particles
  • nvt/sllod - NVT for NEMD with SLLOD equations diff --git a/doc/fix.txt b/doc/fix.txt index a31f5bf0b2..6b824cf10c 100644 --- a/doc/fix.txt +++ b/doc/fix.txt @@ -195,8 +195,10 @@ list of fix styles available in LAMMPS: "nve"_fix_nve.html - constant NVE time integration "nve/asphere"_fix_nve_asphere.html - NVT for aspherical particles "nve/limit"_fix_nve_limit.html - NVE with limited step length +"nve/line"_fix_nve_line.html - NVE for line segments "nve/noforce"_fix_nve_noforce.html - NVE without forces (v only) "nve/sphere"_fix_nve_sphere.html - NVT for spherical particles +"nve/tri"_fix_nve_tri.html - NVE for triangles "nvt"_fix_nh.html - constant NVT time integration via Nose/Hoover "nvt/asphere"_fix_nvt_asphere.html - NVT for aspherical particles "nvt/sllod"_fix_nvt_sllod.html - NVT for NEMD with SLLOD equations diff --git a/doc/fix_nve_line.html b/doc/fix_nve_line.html new file mode 100644 index 0000000000..2a39e7b177 --- /dev/null +++ b/doc/fix_nve_line.html @@ -0,0 +1,60 @@ + +
    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    fix nve/line command +

    +

    Syntax: +

    +
    fix ID group-ID nve/line 
    +
    +
    • ID, group-ID are documented in fix command +
    • nve/line = style name of this fix command +
    +

    Examples: +

    +
    fix 1 all nve/line 
    +
    +

    Description: +

    +

    Perform constant NVE integration to update position, velocity, +orientation, and angular velocity for line segment particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. +

    +

    This fix differs from the fix nve command, which +assumes point particles and only updates their position and velocity. +

    +

    Restart, fix_modify, output, run start/stop, minimize info: +

    +

    No information about this fix is written to binary restart +files. None of the fix_modify options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various output +commands. No parameter of this fix can +be used with the start/stop keywords of the run command. +This fix is not invoked during energy minimization. +

    +

    Restrictions: +

    +

    This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

    +

    This fix requires that particles be line segments as defined by the +atom_style line command. +

    +

    Related commands: +

    +

    fix nve, fix nve/asphere +

    +

    Default: none +

    + diff --git a/doc/fix_nve_line.txt b/doc/fix_nve_line.txt new file mode 100755 index 0000000000..da93f30dbb --- /dev/null +++ b/doc/fix_nve_line.txt @@ -0,0 +1,55 @@ +"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 nve/line command :h3 + +[Syntax:] + +fix ID group-ID nve/line :pre + +ID, group-ID are documented in "fix"_fix.html command +nve/line = style name of this fix command :ul + +[Examples:] + +fix 1 all nve/line :pre + +[Description:] + +Perform constant NVE integration to update position, velocity, +orientation, and angular velocity for line segment particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. + +This fix differs from the "fix nve"_fix_nve.html command, which +assumes point particles and only updates their position and velocity. + +[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 ASPHERE 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. + +This fix requires that particles be line segments as defined by the +"atom_style line"_atom_style.html command. + +[Related commands:] + +"fix nve"_fix_nve.html, "fix nve/asphere"_fix_nve_asphere.html + +[Default:] none diff --git a/doc/fix_nve_tri.html b/doc/fix_nve_tri.html new file mode 100644 index 0000000000..cddb90aba3 --- /dev/null +++ b/doc/fix_nve_tri.html @@ -0,0 +1,60 @@ + +
    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    fix nve/tri command +

    +

    Syntax: +

    +
    fix ID group-ID nve/tri 
    +
    +
    • ID, group-ID are documented in fix command +
    • nve/tri = style name of this fix command +
    +

    Examples: +

    +
    fix 1 all nve/tri 
    +
    +

    Description: +

    +

    Perform constant NVE integration to update position, velocity, +orientation, and angular momentum for triangular particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. +

    +

    This fix differs from the fix nve command, which +assumes point particles and only updates their position and velocity. +

    +

    Restart, fix_modify, output, run start/stop, minimize info: +

    +

    No information about this fix is written to binary restart +files. None of the fix_modify options +are relevant to this fix. No global or per-atom quantities are stored +by this fix for access by various output +commands. No parameter of this fix can +be used with the start/stop keywords of the run command. +This fix is not invoked during energy minimization. +

    +

    Restrictions: +

    +

    This fix is part of the ASPHERE package. It is only enabled if LAMMPS +was built with that package. See the Making +LAMMPS section for more info. +

    +

    This fix requires that particles be triangles as defined by the +atom_style tri command. +

    +

    Related commands: +

    +

    fix nve, fix nve/asphere +

    +

    Default: none +

    + diff --git a/doc/fix_nve_tri.txt b/doc/fix_nve_tri.txt new file mode 100755 index 0000000000..6ea568b4ea --- /dev/null +++ b/doc/fix_nve_tri.txt @@ -0,0 +1,55 @@ +"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 nve/tri command :h3 + +[Syntax:] + +fix ID group-ID nve/tri :pre + +ID, group-ID are documented in "fix"_fix.html command +nve/tri = style name of this fix command :ul + +[Examples:] + +fix 1 all nve/tri :pre + +[Description:] + +Perform constant NVE integration to update position, velocity, +orientation, and angular momentum for triangular particles in the +group each timestep. V is volume; E is energy. This creates a system +trajectory consistent with the microcanonical ensemble. + +This fix differs from the "fix nve"_fix_nve.html command, which +assumes point particles and only updates their position and velocity. + +[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 ASPHERE 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. + +This fix requires that particles be triangles as defined by the +"atom_style tri"_atom_style.html command. + +[Related commands:] + +"fix nve"_fix_nve.html, "fix nve/asphere"_fix_nve_asphere.html + +[Default:] none diff --git a/doc/fix_rigid.html b/doc/fix_rigid.html index 6d92361151..c15ed3ecfe 100644 --- a/doc/fix_rigid.html +++ b/doc/fix_rigid.html @@ -78,12 +78,13 @@ portions of a large biomolecule such as a protein.

    Example of small rigid bodies are patchy nanoparticles, such as those modeled in this paper by Sharon Glotzer's group, clumps of granular particles, lipid molecules consiting of one or more point -dipoles connected to other spheroids or ellipsoids, and coarse-grain -models of nano or colloidal particles consisting of a small number of -constituent particles. Note that the fix shake -command can also be used to rigidify small molecules of 2, 3, or 4 -atoms, e.g. water molecules. That fix treats the constituent atoms as -point masses. +dipoles connected to other spheroids or ellipsoids, irregular +particles built from line segments (2d) or triangles (3d), and +coarse-grain models of nano or colloidal particles consisting of a +small number of constituent particles. Note that the fix +shake command can also be used to rigidify small +molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats +the constituent atoms as point masses.

    These fixes also update the positions and velocities of the atoms in each rigid body via time integration. The rigid and rigid/nve @@ -118,14 +119,14 @@ setforce command), and integrating them as usual


    The constituent particles within a rigid body can be point particles -(the default in LAMMPS) or finite-size particles, such as spheres and -ellipsoids. See the atom_style sphere and ellipsoid -commands for more details on these kinds of particles. Finite-size -particles contribute differently to the moment of inertia of a rigid -body than do point particles. Finite-size particles can also -experience torque (e.g. due to frictional granular -interactions) and have an orientation. These -contributions are accounted for by these fixes. +(the default in LAMMPS) or finite-size particles, such as spheres or +ellipsoids or line segments or triangles. See the atom_style sphere +and ellipsoid and line and tri commands for more +details on these kinds of particles. Finite-size particles contribute +differently to the moment of inertia of a rigid body than do point +particles. Finite-size particles can also experience torque (e.g. due +to frictional granular interactions) and have an +orientation. These contributions are accounted for by these fixes.

    Forces between particles within a body do not contribute to the external force or torque on the body. Thus for computational diff --git a/doc/fix_rigid.txt b/doc/fix_rigid.txt index a6e50b2c07..3d49aedd6d 100644 --- a/doc/fix_rigid.txt +++ b/doc/fix_rigid.txt @@ -67,12 +67,13 @@ portions of a large biomolecule such as a protein. Example of small rigid bodies are patchy nanoparticles, such as those modeled in "this paper"_#Zhang by Sharon Glotzer's group, clumps of granular particles, lipid molecules consiting of one or more point -dipoles connected to other spheroids or ellipsoids, and coarse-grain -models of nano or colloidal particles consisting of a small number of -constituent particles. Note that the "fix shake"_fix_shake.html -command can also be used to rigidify small molecules of 2, 3, or 4 -atoms, e.g. water molecules. That fix treats the constituent atoms as -point masses. +dipoles connected to other spheroids or ellipsoids, irregular +particles built from line segments (2d) or triangles (3d), and +coarse-grain models of nano or colloidal particles consisting of a +small number of constituent particles. Note that the "fix +shake"_fix_shake.html command can also be used to rigidify small +molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats +the constituent atoms as point masses. These fixes also update the positions and velocities of the atoms in each rigid body via time integration. The {rigid} and {rigid/nve} @@ -107,14 +108,14 @@ setforce"_fix_setforce.html command), and integrating them as usual :line The constituent particles within a rigid body can be point particles -(the default in LAMMPS) or finite-size particles, such as spheres and -ellipsoids. See the "atom_style sphere and ellipsoid"_atom_style.html -commands for more details on these kinds of particles. Finite-size -particles contribute differently to the moment of inertia of a rigid -body than do point particles. Finite-size particles can also -experience torque (e.g. due to "frictional granular -interactions"_pair_gran.html) and have an orientation. These -contributions are accounted for by these fixes. +(the default in LAMMPS) or finite-size particles, such as spheres or +ellipsoids or line segments or triangles. See the "atom_style sphere +and ellipsoid and line and tri"_atom_style.html commands for more +details on these kinds of particles. Finite-size particles contribute +differently to the moment of inertia of a rigid body than do point +particles. Finite-size particles can also experience torque (e.g. due +to "frictional granular interactions"_pair_gran.html) and have an +orientation. These contributions are accounted for by these fixes. Forces between particles within a body do not contribute to the external force or torque on the body. Thus for computational diff --git a/doc/fix_srd.html b/doc/fix_srd.html index df029d06fd..8746be8e54 100644 --- a/doc/fix_srd.html +++ b/doc/fix_srd.html @@ -38,10 +38,7 @@ cubic values = style tolerance style = error or warn tolerance = fractional difference allowed (0 <= tol <= 1) - shift values = style seed - style = no or yes or possible - seed = random # seed (positive integer) - stream value = yes or no = whether or not streaming velocity is added for shear deformation + tstat value = yes or no = thermostat SRD particles or not @@ -58,13 +55,14 @@ particles that serve as a background solvent when interacting with big in (Hecht). The key idea behind using SRD particles as a cheap coarse-grained solvent is that SRD particles do not interact with each other, but only with the solute particles, which in LAMMPS -can be spheroids, ellipsoids, or rigid bodies containing multiples -spherioids and ellipsoids. The collision and rotation properties of -the model imbue the SRD particles with fluid-like properties, -including an effective viscosity. Thus simulations with large solute -particles can be run more quickly, to measure solute propoerties like -diffusivity and viscosity in a background fluid. The usual LAMMPS -fixes for such simulations, such as fix deform, fix +can be spheroids, ellipsoids, or line segments, or triangles, or rigid +bodies containing multiple spherioids or ellipsoids or line segments +or triangles. The collision and rotation properties of the model +imbue the SRD particles with fluid-like properties, including an +effective viscosity. Thus simulations with large solute particles can +be run more quickly, to measure solute propoerties like diffusivity +and viscosity in a background fluid. The usual LAMMPS fixes for such +simulations, such as fix deform, fix viscosity, and fix nvt/sllod, can be used in conjunction with the SRD model.

    @@ -272,15 +270,19 @@ must still be specified.

    Note that shifting of SRD coordinates requires extra communication, hence it should not normally be enabled unless required.

    -

    The stream keyword should be used when SRD particles are used with -the fix deform command to perform a simulation -undergoing shear, e.g. to measure a viscosity. If the stream style -is set to yes, then the mean velocity of each bin of SRD particles -is set to the streaming velocity of the deforming box, each time SRD -velocities are reset, every N timesteps. If the stream style is set -to no, then the mean velocity is unchanged, which may mean that it -takes a long time for the SRD fluid to come to equilibrium with a -velocity profile that matches the simulation box deformation. +

    The tstat keyword will thermostat the SRD particles to the specified +Tsrd. This is done every N timesteps, during the velocity rotation +operation, by rescaling the thermal velocity of particles in each SRD +bin to the desired temperature. If there is a streaming velocity +associated with the system, e.g. due to use of the fix +deform command to perform a simulation undergoing +shear, then that is also accounted for. The mean velocity of each bin +of SRD particles is set to the position-dependent streaming velocity, +based on the coordinates of the center of the SRD bin. Note that for +streaming simulations, if no thermostatting is performed (the +default), then it may take a long time for the SRD fluid to come to +equilibrium with a velocity profile that matches the simulation box +deformation.


    @@ -358,7 +360,7 @@ for more info on packages.

    The option defaults are lamda inferred from Tsrd, collision = noslip, overlap = no, inside = error, exact = yes, radius = 1.0, bounce = 0, -search = hgrid, cubic = error 0.01, shift = no, stream = yes. +search = hgrid, cubic = error 0.01, shift = no, tstat = no.


    diff --git a/doc/fix_srd.txt b/doc/fix_srd.txt index a45c21392e..07dd49b861 100644 --- a/doc/fix_srd.txt +++ b/doc/fix_srd.txt @@ -33,10 +33,7 @@ keyword = {lamda} or {collision} or {overlap} or {inside} or {exact} or {radius} {cubic} values = style tolerance style = {error} or {warn} tolerance = fractional difference allowed (0 <= tol <= 1) - {shift} values = style seed - style = {no} or {yes} or {possible} - seed = random # seed (positive integer) - {stream} value = {yes} or {no} = whether or not streaming velocity is added for shear deformation :pre + {tstat} value = {yes} or {no} = thermostat SRD particles or not :pre :ule [Examples:] @@ -52,13 +49,14 @@ particles that serve as a background solvent when interacting with big in "(Hecht)"_#Hecht. The key idea behind using SRD particles as a cheap coarse-grained solvent is that SRD particles do not interact with each other, but only with the solute particles, which in LAMMPS -can be spheroids, ellipsoids, or rigid bodies containing multiples -spherioids and ellipsoids. The collision and rotation properties of -the model imbue the SRD particles with fluid-like properties, -including an effective viscosity. Thus simulations with large solute -particles can be run more quickly, to measure solute propoerties like -diffusivity and viscosity in a background fluid. The usual LAMMPS -fixes for such simulations, such as "fix deform"_fix_deform.html, "fix +can be spheroids, ellipsoids, or line segments, or triangles, or rigid +bodies containing multiple spherioids or ellipsoids or line segments +or triangles. The collision and rotation properties of the model +imbue the SRD particles with fluid-like properties, including an +effective viscosity. Thus simulations with large solute particles can +be run more quickly, to measure solute propoerties like diffusivity +and viscosity in a background fluid. The usual LAMMPS fixes for such +simulations, such as "fix deform"_fix_deform.html, "fix viscosity"_fix_viscosity.html, and "fix nvt/sllod"_fix_nvt_sllod.html, can be used in conjunction with the SRD model. @@ -266,15 +264,19 @@ must still be specified. Note that shifting of SRD coordinates requires extra communication, hence it should not normally be enabled unless required. -The {stream} keyword should be used when SRD particles are used with -the "fix deform"_fix_deform.html command to perform a simulation -undergoing shear, e.g. to measure a viscosity. If the {stream} style -is set to {yes}, then the mean velocity of each bin of SRD particles -is set to the streaming velocity of the deforming box, each time SRD -velocities are reset, every N timesteps. If the {stream} style is set -to {no}, then the mean velocity is unchanged, which may mean that it -takes a long time for the SRD fluid to come to equilibrium with a -velocity profile that matches the simulation box deformation. +The {tstat} keyword will thermostat the SRD particles to the specified +{Tsrd}. This is done every N timesteps, during the velocity rotation +operation, by rescaling the thermal velocity of particles in each SRD +bin to the desired temperature. If there is a streaming velocity +associated with the system, e.g. due to use of the "fix +deform"_fix_deform.html command to perform a simulation undergoing +shear, then that is also accounted for. The mean velocity of each bin +of SRD particles is set to the position-dependent streaming velocity, +based on the coordinates of the center of the SRD bin. Note that for +streaming simulations, if no thermostatting is performed (the +default), then it may take a long time for the SRD fluid to come to +equilibrium with a velocity profile that matches the simulation box +deformation. :line @@ -352,7 +354,7 @@ for more info on packages. The option defaults are lamda inferred from Tsrd, collision = noslip, overlap = no, inside = error, exact = yes, radius = 1.0, bounce = 0, -search = hgrid, cubic = error 0.01, shift = no, stream = yes. +search = hgrid, cubic = error 0.01, shift = no, tstat = no. :line diff --git a/doc/pair_coeff.html b/doc/pair_coeff.html index fb5ffd893a..750a34767b 100644 --- a/doc/pair_coeff.html +++ b/doc/pair_coeff.html @@ -113,6 +113,7 @@ the pair_style command, and coefficients specified by the associated
  • pair_style gran/hooke/history - granular potential without history effects
  • pair_style hbond/dreiding/lj - DREIDING hydrogen bonding LJ potential
  • pair_style hbond/dreiding/morse - DREIDING hydrogen bonding Morse potential +
  • pair_style line/lj - LJ potential between line segments
  • pair_style lj/charmm/coul/charmm - CHARMM potential with cutoff Coulomb
  • pair_style lj/charmm/coul/charmm/implicit - CHARMM for implicit solvent
  • pair_style lj/charmm/coul/long - CHARMM with long-range Coulomb @@ -142,6 +143,7 @@ the pair_style command, and coefficients specified by the associated
  • pair_style table - tabulated pair potential
  • pair_style tersoff - Tersoff 3-body potential
  • pair_style tersoff/zbl - Tersoff/ZBL 3-body potential +
  • pair_style tri/lj - LJ potential between triangles
  • pair_style yukawa - Yukawa potential
  • pair_style yukawa/colloid - screened Yukawa potential for finite-size particles diff --git a/doc/pair_coeff.txt b/doc/pair_coeff.txt index 5a6c00a247..02aebc35f6 100644 --- a/doc/pair_coeff.txt +++ b/doc/pair_coeff.txt @@ -110,6 +110,7 @@ the pair_style command, and coefficients specified by the associated "pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects "pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential "pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential +"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments "pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb "pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent "pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb @@ -139,6 +140,7 @@ the pair_style command, and coefficients specified by the associated "pair_style table"_pair_table.html - tabulated pair potential "pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential "pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential +"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles "pair_style yukawa"_pair_yukawa.html - Yukawa potential "pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul diff --git a/doc/pair_line_lj.html b/doc/pair_line_lj.html new file mode 100644 index 0000000000..125bd41c5d --- /dev/null +++ b/doc/pair_line_lj.html @@ -0,0 +1,117 @@ + +
    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    pair_style line/lj command +

    +

    Syntax: +

    +
    pair_style line/lj cutoff 
    +
    +

    cutoff = global cutoff for interactions (distance units) +

    +

    Examples: +

    +
    pair_style line/lj 3.0
    +pair_coeff * * 1.0 1.0
    +pair_coeff 1 1 1.0 1.5 2.5 
    +
    +

    Description: +

    +

    Style line/lj treats particles which are line segments as a set of +small spherical particles that tile the line segment length as +explained below. Interactions between two line segments, each with N1 +and N2 spherical particles, are calculated as the pairwise sum of +N1*N2 Lennard-Jones interactions. Interactions between a line segment +with N spherical particles and a point particle are treated as the +pairwise sum of N Lennard-Jones interactions. See the pair_style +lj/cut doc page for the definition of Lennard-Jones +interactions. +

    +

    The cutoff distance for an interaction between 2 line segments, or +between a line segment and a point particle, is calculated from the +position of the line segment (its center), not between pairs of +individual spheres comprising the line segment. Thus an interaction +is either calculated in its entirety or not at all. +

    +

    The set of non-overlapping spherical particles that represent a line +segment, for purposes of this pair style, are generated in the +following manner. Their size is a function of the line segment length +and the specified sigma for that particle type. If a line segment has +a length L and is of type I, then the number of spheres N that +represent the segment is calculated as N = L/sigma_II, rounded up to +an integer value. Thus if L is not evenly divisibly by sigam_II, N is +incremented to include one extra sphere. In this case, the spheres +must be slightly smaller than sigma_II so as not to overlap, so a new +sigma-prime is chosen as the sphere diameter, such that L/N = +sigma-prime. Thus the line segment interacts with other segments or +point particles as a collection of N spheres of diameter sigma-prime, +evenly spaced along the line segment, so as to exactly cover its +length. +

    +

    The LJ interaction between 2 spheres on different line segments of +types I,J is computed with an arithmetic mixing of the sigma values of +the 2 spheres and using the specified epsilon value for I,J atom +types. Note that because the sigma values for line segment spheres is +computed using only sigma_II values, specific to the line segment's +type, this means that any specified sigma_IJ values (for I != J) are +effectively ignored. +

    +

    For style line/lj, the following coefficients must be defined for +each pair of atoms types via the pair_coeff command +as in the examples above, or in the data file or restart files read by +the read_data or read_restart +commands: +

    +
    • epsilon (energy units) +
    • sigma (distance units) +
    • cutoff (distance units) +
    +

    The last coefficient is optional. If not specified, the global cutoff +is used. +

    +
    + +

    Mixing, shift, table, tail correction, restart, rRESPA info: +

    +

    For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is geometric. See the "pair_modify" command for +details. +

    +

    This pair style does not support the pair_modify +shift, table, and tail options. +

    +

    This pair style does not write its information to binary restart +files. +

    +

    This pair style can only be used via the pair keyword of the +run_style respa command. It does not support the +inner, middle, outer keywords. +

    +
    + +

    Restrictions: +

    +

    This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info. +

    +

    Defining particles to be line segments so they participate in +line/line or line/particle interactions requires the use the +atom_style line command. +

    +

    Related commands: +

    +

    pair_coeff, pair_style tri/lj +

    +

    Default: none +

    + diff --git a/doc/pair_line_lj.txt b/doc/pair_line_lj.txt new file mode 100644 index 0000000000..7f0bad0830 --- /dev/null +++ b/doc/pair_line_lj.txt @@ -0,0 +1,112 @@ +"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 line/lj command :h3 + +[Syntax:] + +pair_style line/lj cutoff :pre + +cutoff = global cutoff for interactions (distance units) + +[Examples:] + +pair_style line/lj 3.0 +pair_coeff * * 1.0 1.0 +pair_coeff 1 1 1.0 1.5 2.5 :pre + +[Description:] + +Style {line/lj} treats particles which are line segments as a set of +small spherical particles that tile the line segment length as +explained below. Interactions between two line segments, each with N1 +and N2 spherical particles, are calculated as the pairwise sum of +N1*N2 Lennard-Jones interactions. Interactions between a line segment +with N spherical particles and a point particle are treated as the +pairwise sum of N Lennard-Jones interactions. See the "pair_style +lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones +interactions. + +The cutoff distance for an interaction between 2 line segments, or +between a line segment and a point particle, is calculated from the +position of the line segment (its center), not between pairs of +individual spheres comprising the line segment. Thus an interaction +is either calculated in its entirety or not at all. + +The set of non-overlapping spherical particles that represent a line +segment, for purposes of this pair style, are generated in the +following manner. Their size is a function of the line segment length +and the specified sigma for that particle type. If a line segment has +a length L and is of type I, then the number of spheres N that +represent the segment is calculated as N = L/sigma_II, rounded up to +an integer value. Thus if L is not evenly divisibly by sigam_II, N is +incremented to include one extra sphere. In this case, the spheres +must be slightly smaller than sigma_II so as not to overlap, so a new +sigma-prime is chosen as the sphere diameter, such that L/N = +sigma-prime. Thus the line segment interacts with other segments or +point particles as a collection of N spheres of diameter sigma-prime, +evenly spaced along the line segment, so as to exactly cover its +length. + +The LJ interaction between 2 spheres on different line segments of +types I,J is computed with an arithmetic mixing of the sigma values of +the 2 spheres and using the specified epsilon value for I,J atom +types. Note that because the sigma values for line segment spheres is +computed using only sigma_II values, specific to the line segment's +type, this means that any specified sigma_IJ values (for I != J) are +effectively ignored. + +For style {line/lj}, the following coefficients must be defined for +each pair of atoms types via the "pair_coeff"_pair_coeff.html command +as in the examples above, or in the data file or restart files read by +the "read_data"_read_data.html or "read_restart"_read_restart.html +commands: + +epsilon (energy units) +sigma (distance units) +cutoff (distance units) :ul + +The last coefficient is optional. If not specified, the global cutoff +is used. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is {geometric}. See the "pair_modify" command for +details. + +This pair style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. + +This pair style does not write its information to "binary restart +files"_restart.html. + +This pair style can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. It does not support the +{inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] + +This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + +Defining particles to be line segments so they participate in +line/line or line/particle interactions requires the use the +"atom_style line"_atom_style.html command. + +[Related commands:] + +"pair_coeff"_pair_coeff.html, "pair_style tri/lj"_pair_tri_lj.html + +[Default:] none diff --git a/doc/pair_style.html b/doc/pair_style.html index 0fd6871819..b00d2360e5 100644 --- a/doc/pair_style.html +++ b/doc/pair_style.html @@ -115,6 +115,7 @@ the pair_style command, and coefficients specified by the associated
  • pair_style gran/hooke/history - granular potential without history effects
  • pair_style hbond/dreiding/lj - DREIDING hydrogen bonding LJ potential
  • pair_style hbond/dreiding/morse - DREIDING hydrogen bonding Morse potential +
  • pair_style line/lj - LJ potential between line segments
  • pair_style lj/charmm/coul/charmm - CHARMM potential with cutoff Coulomb
  • pair_style lj/charmm/coul/charmm/implicit - CHARMM for implicit solvent
  • pair_style lj/charmm/coul/long - CHARMM with long-range Coulomb @@ -144,6 +145,7 @@ the pair_style command, and coefficients specified by the associated
  • pair_style table - tabulated pair potential
  • pair_style tersoff - Tersoff 3-body potential
  • pair_style tersoff/zbl - Tersoff/ZBL 3-body potential +
  • pair_style tri/lj - LJ potential between triangles
  • pair_style yukawa - Yukawa potential
  • pair_style yukawa/colloid - screened Yukawa potential for finite-size particles diff --git a/doc/pair_style.txt b/doc/pair_style.txt index d7ae16d690..c450e3272a 100644 --- a/doc/pair_style.txt +++ b/doc/pair_style.txt @@ -112,6 +112,7 @@ the pair_style command, and coefficients specified by the associated "pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects "pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential "pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential +"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments "pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb "pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent "pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb @@ -141,6 +142,7 @@ the pair_style command, and coefficients specified by the associated "pair_style table"_pair_table.html - tabulated pair potential "pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential "pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential +"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles "pair_style yukawa"_pair_yukawa.html - Yukawa potential "pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul diff --git a/doc/pair_sw.html b/doc/pair_sw.html index fe1fa3b116..6ea6f91277 100644 --- a/doc/pair_sw.html +++ b/doc/pair_sw.html @@ -11,6 +11,8 @@

    pair_style sw command

    +

    pair_style sw/cuda command +

    pair_style sw/omp command

    Syntax: diff --git a/doc/pair_sw.txt b/doc/pair_sw.txt index d1ea462f1b..6395470c8a 100644 --- a/doc/pair_sw.txt +++ b/doc/pair_sw.txt @@ -7,6 +7,7 @@ :line pair_style sw command :h3 +pair_style sw/cuda command :h3 pair_style sw/omp command :h3 [Syntax:] diff --git a/doc/pair_tersoff.html b/doc/pair_tersoff.html index 96f629494a..9686352730 100644 --- a/doc/pair_tersoff.html +++ b/doc/pair_tersoff.html @@ -15,6 +15,8 @@

    pair_style tersoff 
     
    +
    pair_style tersoff/cuda 
    +
    pair_style tersoff/omp 
     

    Examples: @@ -133,7 +135,7 @@ equivalent form for alloys, which we will refer to as Tersoff_2 potential (Tersoff_2).

    LAMMPS parameter values for Tersoff_2 can be obtained as follows: -gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of +gamma_ijk = omega_ik, lambda3 = 0 and the value of m has no effect. The parameters for species i and j can be calculated using the Tersoff_2 mixing rules:

    diff --git a/doc/pair_tersoff.txt b/doc/pair_tersoff.txt index 2f0f539e95..5d23f009f3 100644 --- a/doc/pair_tersoff.txt +++ b/doc/pair_tersoff.txt @@ -11,6 +11,7 @@ pair_style tersoff command :h3 [Syntax:] pair_style tersoff :pre +pair_style tersoff/cuda :pre pair_style tersoff/omp :pre [Examples:] @@ -129,7 +130,7 @@ equivalent form for alloys, which we will refer to as Tersoff_2 potential "(Tersoff_2)"_#Tersoff_2. LAMMPS parameter values for Tersoff_2 can be obtained as follows: -gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of +gamma_ijk = omega_ik, lambda3 = 0 and the value of m has no effect. The parameters for species i and j can be calculated using the Tersoff_2 mixing rules: diff --git a/doc/pair_tri_lj.html b/doc/pair_tri_lj.html new file mode 100644 index 0000000000..76b4455fe7 --- /dev/null +++ b/doc/pair_tri_lj.html @@ -0,0 +1,120 @@ + +
    LAMMPS WWW Site - LAMMPS Documentation - LAMMPS Commands +
    + + + + + + +
    + +

    pair_style tri/lj command +

    +

    Syntax: +

    +
    pair_style tri/lj cutoff 
    +
    +

    cutoff = global cutoff for interactions (distance units) +

    +

    Examples: +

    +
    pair_style tri/lj 3.0
    +pair_coeff * * 1.0 1.0
    +pair_coeff 1 1 1.0 1.5 2.5 
    +
    +

    Description: +

    +

    Style tri/lj treats particles which are triangles as a set of small +spherical particles that tile the triangle surface as explained below. +Interactions between two triangles, each with N1 and N2 spherical +particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones +interactions. Interactions between a triangle with N spherical +particles and a point particle are treated as the pairwise sum of N +Lennard-Jones interactions. See the pair_style lj/cut +doc page for the definition of Lennard-Jones interactions. +

    +

    The cutoff distance for an interaction between 2 triangles, or between +a triangle and a point particle, is calculated from the position of +the triangle (its centroid), not between pairs of individual spheres +comprising the triangle. Thus an interaction is either calculated in +its entirety or not at all. +

    +

    The set of non-overlapping spherical particles that represent a +triangle, for purposes of this pair style, are generated in the +following manner. Assume the triangle is of type I, and sigma_II has +been specified. We want a set of spheres with centers in the plane of +the triangle, none of them larger in diameter than sigma_II, which +completely cover the triangle's area, but with minimial overlap and a +minimal total number of spheres. This is done in a recursive manner. +Place a sphere at the centroid of the original triangle. Calculate +what diameter it must have to just cover all 3 corner points of the +triangle. If that diameter is equal to or smaller than sigma_II, then +include a sphere of the calculated diameter in the set of covering +spheres. It the diameter is larger than sigma_II, then split the +triangle into 2 triangles by bisecting its longest side. Repeat the +process on each sub-triangle, recursing as far as needed to generate a +set of covering spheres. When finished, the original criteria are +met, and the set of covering spheres shoule be near minimal in number +and overlap, at least for input triangles with a reasonable +aspect-ratio. +

    +

    The LJ interaction between 2 spheres on different triangles of types +I,J is computed with an arithmetic mixing of the sigma values of the 2 +spheres and using the specified epsilon value for I,J atom types. +Note that because the sigma values for triangles spheres is computed +using only sigma_II values, specific to the triangles's type, this +means that any specified sigma_IJ values (for I != J) are effectively +ignored. +

    +

    For style tri/lj, the following coefficients must be defined for +each pair of atoms types via the pair_coeff command +as in the examples above, or in the data file or restart files read by +the read_data or read_restart +commands: +

    +
    • epsilon (energy units) +
    • sigma (distance units) +
    • cutoff (distance units) +
    +

    The last coefficient is optional. If not specified, the global cutoff +is used. +

    +
    + +

    Mixing, shift, table, tail correction, restart, rRESPA info: +

    +

    For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is geometric. See the "pair_modify" command for +details. +

    +

    This pair style does not support the pair_modify +shift, table, and tail options. +

    +

    This pair style does not write its information to binary restart +files. +

    +

    This pair style can only be used via the pair keyword of the +run_style respa command. It does not support the +inner, middle, outer keywords. +

    +
    + +

    Restrictions: +

    +

    This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the Making +LAMMPS section for more info. +

    +

    Defining particles to be triangles so they participate in tri/tri or +tri/particle interactions requires the use the atom_style +tri command. +

    +

    Related commands: +

    +

    pair_coeff, pair_style line/lj +

    +

    Default: none +

    + diff --git a/doc/pair_tri_lj.txt b/doc/pair_tri_lj.txt new file mode 100644 index 0000000000..cfc64c52fd --- /dev/null +++ b/doc/pair_tri_lj.txt @@ -0,0 +1,115 @@ +"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 tri/lj command :h3 + +[Syntax:] + +pair_style tri/lj cutoff :pre + +cutoff = global cutoff for interactions (distance units) + +[Examples:] + +pair_style tri/lj 3.0 +pair_coeff * * 1.0 1.0 +pair_coeff 1 1 1.0 1.5 2.5 :pre + +[Description:] + +Style {tri/lj} treats particles which are triangles as a set of small +spherical particles that tile the triangle surface as explained below. +Interactions between two triangles, each with N1 and N2 spherical +particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones +interactions. Interactions between a triangle with N spherical +particles and a point particle are treated as the pairwise sum of N +Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html +doc page for the definition of Lennard-Jones interactions. + +The cutoff distance for an interaction between 2 triangles, or between +a triangle and a point particle, is calculated from the position of +the triangle (its centroid), not between pairs of individual spheres +comprising the triangle. Thus an interaction is either calculated in +its entirety or not at all. + +The set of non-overlapping spherical particles that represent a +triangle, for purposes of this pair style, are generated in the +following manner. Assume the triangle is of type I, and sigma_II has +been specified. We want a set of spheres with centers in the plane of +the triangle, none of them larger in diameter than sigma_II, which +completely cover the triangle's area, but with minimial overlap and a +minimal total number of spheres. This is done in a recursive manner. +Place a sphere at the centroid of the original triangle. Calculate +what diameter it must have to just cover all 3 corner points of the +triangle. If that diameter is equal to or smaller than sigma_II, then +include a sphere of the calculated diameter in the set of covering +spheres. It the diameter is larger than sigma_II, then split the +triangle into 2 triangles by bisecting its longest side. Repeat the +process on each sub-triangle, recursing as far as needed to generate a +set of covering spheres. When finished, the original criteria are +met, and the set of covering spheres shoule be near minimal in number +and overlap, at least for input triangles with a reasonable +aspect-ratio. + +The LJ interaction between 2 spheres on different triangles of types +I,J is computed with an arithmetic mixing of the sigma values of the 2 +spheres and using the specified epsilon value for I,J atom types. +Note that because the sigma values for triangles spheres is computed +using only sigma_II values, specific to the triangles's type, this +means that any specified sigma_IJ values (for I != J) are effectively +ignored. + +For style {tri/lj}, the following coefficients must be defined for +each pair of atoms types via the "pair_coeff"_pair_coeff.html command +as in the examples above, or in the data file or restart files read by +the "read_data"_read_data.html or "read_restart"_read_restart.html +commands: + +epsilon (energy units) +sigma (distance units) +cutoff (distance units) :ul + +The last coefficient is optional. If not specified, the global cutoff +is used. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +For atom type pairs I,J and I != J, the epsilon and sigma coefficients +and cutoff distance for all of this pair style can be mixed. The +default mix value is {geometric}. See the "pair_modify" command for +details. + +This pair style does not support the "pair_modify"_pair_modify.html +shift, table, and tail options. + +This pair style does not write its information to "binary restart +files"_restart.html. + +This pair style can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. It does not support the +{inner}, {middle}, {outer} keywords. + +:line + +[Restrictions:] + +This style is part of the ASPHERE package. It is only enabled if +LAMMPS was built with that package. See the "Making +LAMMPS"_Section_start.html#2_3 section for more info. + +Defining particles to be triangles so they participate in tri/tri or +tri/particle interactions requires the use the "atom_style +tri"_atom_style.html command. + +[Related commands:] + +"pair_coeff"_pair_coeff.html, "pair_style line/lj"_pair_line_lj.html + +[Default:] none diff --git a/doc/read_data.html b/doc/read_data.html index bd2e87918f..fcf68f4680 100644 --- a/doc/read_data.html +++ b/doc/read_data.html @@ -80,6 +80,8 @@ is different than the default.
  • improper types = # of improper types in system
  • extra bond per atom = leave space for this many new bonds per atom
  • ellipsoids = # of ellipsoids in system +
  • lines = # of line segments in system +
  • triangles = # of triangles in system
  • xlo xhi = simulation box boundaries in x dimension
  • ylo yhi = simulation box boundaries in y dimension
  • zlo zhi = simulation box boundaries in z dimension @@ -156,16 +158,19 @@ added to the system when a simulation runs, e.g. by using the setting is only used with atom_style -ellipsoid and specifies how many of the atoms are -finite-size ellipsoids; the remainder are point particles. See the -discussion of ellipseflag and the Ellipsoids section below. +

    The "ellipsoids" and "lines" and "triangles" settings are only used +with atom_style ellipsoid or line or tri and +specifies how many of the atoms are finite-size ellipsoids or lines or +triangles; the remainder are point particles. See the discussion of +ellipsoidflag and the Ellipsoids section below. See the discussion +of lineflag and the Lines section below. See the discussion of +triangleflag and the Triangles section below.


    These are the section keywords for the body of the file.

    -
    • Atoms, Velocities, Ellipsoids, Masses = atom-property sections +
      • Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles = atom-property sections
      • Bonds, Angles, Dihedrals, Impropers = molecular topology sections
      • Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, Improper Coeffs = force field sections
      • BondBond Coeffs, BondAngle Coeffs, MiddleBondTorsion Coeffs, EndBondTorsion Coeffs, AngleTorsion Coeffs, AngleAngleTorsion Coeffs, BondBond13 Coeffs, AngleAngle Coeffs = class 2 force field sections @@ -290,10 +295,12 @@ of analysis. 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 +line atom-ID molecule-ID atom-type lineflag density x y z meso atom-ID atom-type rho e cv x y z molecular atom-ID molecule-ID atom-type x y z peri atom-ID atom-type volume density x y z sphere atom-ID atom-type diameter density x y z +tri atom-ID molecule-ID atom-type triangleflag density x y z wavepacket atom-ID atom-type charge spin eradius etag cs_re cs_im x y z hybrid atom-ID atom-type x y z sub-style1 sub-style2 ... @@ -306,7 +313,9 @@ of analysis.
      • q = charge on atom (charge units)
      • diameter = diameter of spherical atom (distance units)
      • ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles -
      • density = density of atom (mass/distance^3 units) +
      • lineflag = 1 for line segment particles, 0 for point particles +
      • triangleflag = 1 for triangular particles, 0 for point particles +
      • density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
      • volume = volume of atom (distance^3 units)
      • x,y,z = coordinates of atom
      • mux,muy,muz = components of dipole moment of atom (dipole units) @@ -342,9 +351,13 @@ keep track of molecule assignments.

        The diameter specifies the size of a finite-size spherical particle. It can be set to 0.0, which means that atom is a point particle.

        -

        The ellipseflag determines whether the particle is a finite-size -ellipsoid of finite size, or a point particle. Additional attributes -must be defined for each ellipsoid in the Ellipsoids section. +

        The ellipsoidflag, lineflag, and triangleflag determine whether the +particle is a finite-size ellipsoid or line or triangle of finite +size, or a point particle. Additional attributes must be defined for +each ellipsoid in the Ellipsoids section. Additional attributes +must be defined for each line in the Lines section. Additional +attributes must be defined for each triangle in the Triangles +section.

        Some pair styles and fixes and computes that operate on finite-size particles allow for a mixture of finite-size and point particles. See @@ -352,8 +365,10 @@ the doc pages of individual commands for details.

        The density is used in conjunction with the particle volume for finite-size particles to set the mass of the particle as mass = -density * volume. If the volume is 0.0, meaning a point particle, -then the density value is used as the mass. +density * volume. In this context, volume can be a 3d quantity (for +spheres or ellipsoids), a 2d quantity (for triangles), or a 1d +quantity (for line segments). If the volume is 0.0, meaning a point +particle, then the density value is used as the mass.

        For atom_style hybrid, following the 5 initial values (ID,type,x,y,z), specific values for each sub-style must be listed. The order of the @@ -530,15 +545,12 @@ section must be integers (1, not 1.0).

      • line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk -
          atom-ID = ID of atom which is an ellipsoid
        +
      • atom-ID = ID of atom which is an ellipsoid shapex,shapey,shapez = 3 diameters of ellipsoid (distance units) quatw,quati,quatj,quatk = quaternion components for orientation of atom -type = bond type (1-Nbondtype) - atom1,atom2 = IDs of 1st,2nd atoms in bond -
      • -
      • example: +example: -
          12 3 17 29 
        +
          12 1 2 1 1 0 0 0 
         
      @@ -630,6 +642,37 @@ values in this section must be integers (1, not 1.0).


      +

      Lines section: +

      +
      • one line per line segment + +
      • line syntax: atom-ID x1 y1 x2 y2 + +
      • atom-ID = ID of atom which is a line segment + x1,y1 = 1st end point + x2,y2 = 2nd end point +example: + +
          12 1.0 0.0 2.0 0.0 
        +
        + +
      +

      The Lines section must appear if atom_style line +is used and any atoms are listed in the Atoms section with a +lineflag = 1. The number of lines should be specified in the header +section via the "lines" keyword. +

      +

      The 2 end points are the end points of the line segment. The ordering +of the 2 points should be such that using a right-hand rule to cross +the line segment with a unit vector in the +z direction, gives an +"outward" normal vector perpendicular to the line segment. +I.e. normal = (c2-c1) x (0,0,1). This orientation may be important +for defining some interactions. +

      +

      The Lines section must appear after the Atoms section. +

      +
      +

      Masses section:

      • one line per atom type @@ -688,6 +731,37 @@ script.


        +

        Triangles section: +

        +
        • one line per triangle + +
        • line syntax: atom-ID x1 y1 x2 y2 + +
        • atom-ID = ID of atom which is a line segment + x1,y1,z1 = 1st corner point + x2,y2,z2 = 2nd corner point + x3,y3,z3 = 3rd corner point +example: + +
            12 0.0 0.0 0.0 2.0 0.0 1.0 0.0 2.0 1.0 
          +
          + +
        +

        The Triangles section must appear if atom_style +tri is used and any atoms are listed in the Atoms +section with a triangleflag = 1. The number of lines should be +specified in the header section via the "triangles" keyword. +

        +

        The 3 corner points are the corner points of the triangle. The +ordering of the 3 points should be such that using a right-hand rule +to go from point1 to point2 to point3 gives an "outward" normal vector +to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This +orientation may be important for defining some interactions. +

        +

        The Triangles section must appear after the Atoms section. +

        +
        +

        Velocities section:

        • one line per atom diff --git a/doc/read_data.txt b/doc/read_data.txt index e2d1c0437c..b9fcccd0f6 100644 --- a/doc/read_data.txt +++ b/doc/read_data.txt @@ -77,6 +77,8 @@ is different than the default. {improper types} = # of improper types in system {extra bond per atom} = leave space for this many new bonds per atom {ellipsoids} = # of ellipsoids in system +{lines} = # of line segments in system +{triangles} = # of triangles in system {xlo xhi} = simulation box boundaries in x dimension {ylo yhi} = simulation box boundaries in y dimension {zlo zhi} = simulation box boundaries in z dimension @@ -153,16 +155,19 @@ 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. -The "ellipsoids" setting is only used with atom_style -ellipsoid"_atom_style.html and specifies how many of the atoms are -finite-size ellipsoids; the remainder are point particles. See the -discussion of ellipseflag and the {Ellipsoids} section below. +The "ellipsoids" and "lines" and "triangles" settings are only used +with "atom_style ellipsoid or line or tri"_atom_style.html and +specifies how many of the atoms are finite-size ellipsoids or lines or +triangles; the remainder are point particles. See the discussion of +ellipsoidflag and the {Ellipsoids} section below. See the discussion +of lineflag and the {Lines} section below. See the discussion of +triangleflag and the {Triangles} section below. :line These are the section keywords for the body of the file. -{Atoms, Velocities, Ellipsoids, Masses} = atom-property sections +{Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles} = atom-property sections {Bonds, Angles, Dihedrals, Impropers} = molecular topology sections {Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, \ Improper Coeffs} = force field sections @@ -270,10 +275,12 @@ 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 ellipsoidflag density x y z full: atom-ID molecule-ID atom-type q x y z +line: atom-ID molecule-ID atom-type lineflag density x y z meso: atom-ID atom-type rho e cv x y z molecular: atom-ID molecule-ID atom-type x y z peri: atom-ID atom-type volume density x y z sphere: atom-ID atom-type diameter density x y z +tri: atom-ID molecule-ID atom-type triangleflag density x y z wavepacket: atom-ID atom-type charge spin eradius etag cs_re cs_im x y z hybrid: atom-ID atom-type x y z sub-style1 sub-style2 ... :tb(s=:) @@ -285,7 +292,9 @@ atom-type = type of atom (1-Ntype) q = charge on atom (charge units) diameter = diameter of spherical atom (distance units) ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles -density = density of atom (mass/distance^3 units) +lineflag = 1 for line segment particles, 0 for point particles +triangleflag = 1 for triangular particles, 0 for point particles +density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) volume = volume of atom (distance^3 units) x,y,z = coordinates of atom mux,muy,muz = components of dipole moment of atom (dipole units) @@ -321,9 +330,13 @@ keep track of molecule assignments. The diameter specifies the size of a finite-size spherical particle. It can be set to 0.0, which means that atom is a point particle. -The ellipseflag determines whether the particle is a finite-size -ellipsoid of finite size, or a point particle. Additional attributes -must be defined for each ellipsoid in the {Ellipsoids} section. +The ellipsoidflag, lineflag, and triangleflag determine whether the +particle is a finite-size ellipsoid or line or triangle of finite +size, or a point particle. Additional attributes must be defined for +each ellipsoid in the {Ellipsoids} section. Additional attributes +must be defined for each line in the {Lines} section. Additional +attributes must be defined for each triangle in the {Triangles} +section. Some pair styles and fixes and computes that operate on finite-size particles allow for a mixture of finite-size and point particles. See @@ -331,8 +344,10 @@ the doc pages of individual commands for details. The density is used in conjunction with the particle volume for finite-size particles to set the mass of the particle as mass = -density * volume. If the volume is 0.0, meaning a point particle, -then the density value is used as the mass. +density * volume. In this context, volume can be a 3d quantity (for +spheres or ellipsoids), a 2d quantity (for triangles), or a 1d +quantity (for line segments). If the volume is 0.0, meaning a point +particle, then the density value is used as the mass. For atom_style hybrid, following the 5 initial values (ID,type,x,y,z), specific values for each sub-style must be listed. The order of the @@ -481,10 +496,8 @@ line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk :l atom-ID = ID of atom which is an ellipsoid shapex,shapey,shapez = 3 diameters of ellipsoid (distance units) quatw,quati,quatj,quatk = quaternion components for orientation of atom -type = bond type (1-Nbondtype) - atom1,atom2 = IDs of 1st,2nd atoms in bond :pre example: :l - 12 3 17 29 :pre + 12 1 2 1 1 0 0 0 :pre :ule The {Ellipsoids} section must appear if "atom_style @@ -562,6 +575,33 @@ values in this section must be integers (1, not 1.0). :line +{Lines} section: + +one line per line segment :ulb,l +line syntax: atom-ID x1 y1 x2 y2 :l + atom-ID = ID of atom which is a line segment + x1,y1 = 1st end point + x2,y2 = 2nd end point +example: :l + 12 1.0 0.0 2.0 0.0 :pre +:ule + +The {Lines} section must appear if "atom_style line"_atom_style.html +is used and any atoms are listed in the {Atoms} section with a +lineflag = 1. The number of lines should be specified in the header +section via the "lines" keyword. + +The 2 end points are the end points of the line segment. The ordering +of the 2 points should be such that using a right-hand rule to cross +the line segment with a unit vector in the +z direction, gives an +"outward" normal vector perpendicular to the line segment. +I.e. normal = (c2-c1) x (0,0,1). This orientation may be important +for defining some interactions. + +The {Lines} section must appear after the {Atoms} section. + +:line + {Masses} section: one line per atom type :ulb,l @@ -607,6 +647,33 @@ script. :line +{Triangles} section: + +one line per triangle :ulb,l +line syntax: atom-ID x1 y1 x2 y2 :l + atom-ID = ID of atom which is a line segment + x1,y1,z1 = 1st corner point + x2,y2,z2 = 2nd corner point + x3,y3,z3 = 3rd corner point +example: :l + 12 0.0 0.0 0.0 2.0 0.0 1.0 0.0 2.0 1.0 :pre +:ule + +The {Triangles} section must appear if "atom_style +tri"_atom_style.html is used and any atoms are listed in the {Atoms} +section with a triangleflag = 1. The number of lines should be +specified in the header section via the "triangles" keyword. + +The 3 corner points are the corner points of the triangle. The +ordering of the 3 points should be such that using a right-hand rule +to go from point1 to point2 to point3 gives an "outward" normal vector +to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This +orientation may be important for defining some interactions. + +The {Triangles} section must appear after the {Atoms} section. + +:line + {Velocities} section: one line per atom diff --git a/doc/set.html b/doc/set.html index a1feb65a31..06be9fb51c 100644 --- a/doc/set.html +++ b/doc/set.html @@ -21,7 +21,7 @@
        • one or more keyword/value pairs may be appended -
        • keyword = type or type/fraction or mol or x or y or z or charge or dipole or dipole/random or quat or quat/random or diameter or shape or mass or density or volume or image or +
        • keyword = type or type/fraction or mol or x or y or z or charge or dipole or dipole/random or quat or quat/random or diameter or shape or length or tri or theta or angmom or mass or density or volume or image or bond or angle or dihedral or improper or meso_e or meso_cv or meso_rho @@ -40,14 +40,22 @@ Dlen = magnitude of dipole moment (dipole units) quat values = a b c theta a,b,c = unit vector to rotate particle around via right-hand rule - theta = rotation angle in degrees + theta = rotation angle (degrees) quat/random value = seed seed = random # seed (positive integer) for quaternion orientations diameter value = diameter of spherical particle (distance units) shape value = Sx Sy Sz Sx,Sy,Sz = 3 diameters of ellipsoid (distance units) + length value = len + len = length of line segment (distance units) + tri value = side + side = side length of equilateral triangle (distance units) + theta value = angle (degrees) + angle = orientation of line segment with respect to x-axis + angmom values = Lx Ly Lz + Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units) mass value = per-atom mass (mass units) - density value = particle density for sphere or ellipsoid (mass/distance^3 units) + density value = particle density for sphere or ellipsoid (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) volume value = particle volume for Peridynamic particle (distance^3 units) image nx ny nz nx,ny,nz = which periodic image of the simulation box the atom is in @@ -143,26 +151,31 @@ the orientation of a particular atom is the same, regardless of how many processors are being used.

          Keyword quat uses the specified values to create a quaternion -(4-vector) that represents the orientation of the selected atoms. -Note that particles defined by atom_style ellipsoid -have 3 shape parameters. The 3 values must be non-zero for each -particle set by this command. They are used to specify the aspect -ratios of an ellipsoidal particle, which is oriented by default with -its x-axis along the simulation box's x-axis, and similarly for y and -z. If this body is rotated (via the right-hand rule) by an angle -theta around a unit rotation vector (a,b,c), then the quaternion that -represents its new orientation is given by (cos(theta/2), -a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). The theta and a,b,c -values are the arguments to the quat keyword. LAMMPS normalizes the -quaternion in case (a,b,c) was not specified as a unit vector. For 2d -systems, the a,b,c values are ignored, since a rotation vector of -(0,0,1) is the only valid choice. +(4-vector) that represents the orientation of the selected atoms. The +particles must be ellipsoids as defined by the atom_style +ellipsoid command or triangles as defined by the +atom_style tri command. Note that particles defined +by atom_style ellipsoid have 3 shape parameters. +The 3 values must be non-zero for each particle set by this command. +They are used to specify the aspect ratios of an ellipsoidal particle, +which is oriented by default with its x-axis along the simulation +box's x-axis, and similarly for y and z. If this body is rotated (via +the right-hand rule) by an angle theta around a unit rotation vector +(a,b,c), then the quaternion that represents its new orientation is +given by (cos(theta/2), a*sin(theta/2), b*sin(theta/2), +c*sin(theta/2)). The theta and a,b,c values are the arguments to the +quat keyword. LAMMPS normalizes the quaternion in case (a,b,c) was +not specified as a unit vector. For 2d systems, the a,b,c values are +ignored, since a rotation vector of (0,0,1) is the only valid choice.

          Keyword quat/random randomizes the orientation of the quaternion of -the selected atoms. Random numbers are used in such a way that the -orientation of a particular atom is the same, regardless of how many -processors are being used. For 2d systems, only orientations in the -xy plane are generated. As with keyword quat, the 3 shape values +the selected atoms. The particles must be ellipsoids as defined by +the atom_style ellipsoid command or triangles as +defined by the atom_style tri command. Random +numbers are used in such a way that the orientation of a particular +atom is the same, regardless of how many processors are being used. +For 2d systems, only orientations in the xy plane are generated. As +with keyword quat, for ellipsoidal particles, the 3 shape values must be non-zero for each particle set by this command.

          Keyword diameter sets the size of the selected atoms. The particles @@ -174,7 +187,7 @@ defined with a density, e.g. via the read_data command.

          Keyword shape sets the size and shape of the selected atoms. The -particles must be aspherical ellipsoids as defined by the atom_style +particles must be ellipsoids as defined by the atom_style ellipsoid command. The Sx, Sy, Sz settings are the 3 diameters of the ellipsoid in each direction. All 3 can be set to the same value, which means the ellipsoid is effectively a sphere. @@ -183,20 +196,60 @@ treated as a point particle. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the read_data command.

          +

          Keyword length sets the length of selected atoms. The particles +must be line segments as defined by the atom_style +line command. If the specified value is non-zero the +line segment is (re)set to a length = the specified value, centered +around the particle position, with an orientation along the x-axis. +If the specified value is 0.0, the particle will become a point +particle. Note that this command does not adjust the particle mass, +even if it was defined with a density, e.g. via the +read_data command. +

          +

          Keyword tri sets the size of selected atoms. The particles must be +triangles as defined by the atom_style tri command. +If the specified value is non-zero the triangle is (re)set to be an +equilateral triangle in the xy plane with side length = the specified +value, with a centroid at the particle position, with its base +parallel to the x axis, and the y-axis running from the center of the +base to the top point of the triangle. If the specified value is 0.0, +the particle will become a point particle. Note that this command +does not adjust the particle mass, even if it was defined with a +density, e.g. via the read_data command. +

          +

          Keyword theta sets the orientation of selected atoms. The particles +must be line segments as defined by the atom_style +line command. The specified value is used to set the +orientation angle of the line segments with respect to the x axis. +

          +

          Keyword angmom sets the angular momentum of selected atoms. The +particles must be ellipsoids as defined by the atom_style +ellipsoid command or triangles as defined by the +atom_style tri command. The angular momentum vector +of the particles is set to the 3 specified components. +

          Keyword mass sets the mass of all selected particles. The particles must have a per-atom mass attribute, as defined by the atom_style command. See the "mass" command for how to set mass values on a per-type basis.

          -

          Keyword density sets the mass of all selected particles. The -particles must have a per-atom mass attribute, as defined by the -atom_style command. See the "mass" command for how -to set mass values on a per-type basis. If the atom has a radius -attribute (see atom_style sphere) and its radius is -non-zero, its mass is set from the density and particle volume. The -same is true if the atom has a shape attribute (see atom_style -ellipsoid) and its 3 shape parameters are non-zero. -Otherwise the mass is set to the density value directly. +

          Keyword density also sets the mass of all selected particles, but in +a different way. The particles must have a per-atom mass attribute, +as defined by the atom_style command. If the atom +has a radius attribute (see atom_style sphere) and +its radius is non-zero, its mass is set from the density and particle +volume. If the atom has a shape attribute (see atom_style +ellipsoid) and its 3 shape parameters are non-zero, +then its mass is set from the density and particle volume. If the +atom has a length attribute (see atom_style line) +and its length is non-zero, then its mass is set from the density and +line segment length (the input density is assumed to be in +mass/distance units). If the atom has an area attribute (see +atom_style tri) and its area is non-zero, then its +mass is set from the density and triangle area (the input density is +assumed to be in mass/distance^2 units). If none of these cases are +valid, then the mass is set to the density value directly (the input +density is assumed to be in mass units).

          Keyword volume sets the volume of all selected particles. Currently, only the atom_style peri command defines diff --git a/doc/set.txt b/doc/set.txt index 8f37b29f1b..0c352d0958 100644 --- a/doc/set.txt +++ b/doc/set.txt @@ -17,8 +17,9 @@ ID = atom ID range or type range or mol ID range or group ID or region ID :l one or more keyword/value pairs may be appended :l keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ {charge} or {dipole} or {dipole/random} or {quat} or \ - {quat/random} or {diameter} or {shape} or {mass} or \ - {density} or {volume} or {image} or + {quat/random} or {diameter} or {shape} or \ + {length} or {tri} or {theta} or {angmom} or \ + {mass} or {density} or {volume} or {image} or {bond} or {angle} or {dihedral} or {improper} or {meso_e} or {meso_cv} or {meso_rho} :l {type} value = atom type @@ -36,14 +37,22 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ Dlen = magnitude of dipole moment (dipole units) {quat} values = a b c theta a,b,c = unit vector to rotate particle around via right-hand rule - theta = rotation angle in degrees + theta = rotation angle (degrees) {quat/random} value = seed seed = random # seed (positive integer) for quaternion orientations {diameter} value = diameter of spherical particle (distance units) {shape} value = Sx Sy Sz Sx,Sy,Sz = 3 diameters of ellipsoid (distance units) + {length} value = len + len = length of line segment (distance units) + {tri} value = side + side = side length of equilateral triangle (distance units) + {theta} value = angle (degrees) + angle = orientation of line segment with respect to x-axis + {angmom} values = Lx Ly Lz + Lx,Ly,Lz = components of angular momentum vector (distance-mass-velocity units) {mass} value = per-atom mass (mass units) - {density} value = particle density for sphere or ellipsoid (mass/distance^3 units) + {density} value = particle density for sphere or ellipsoid (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle) {volume} value = particle volume for Peridynamic particle (distance^3 units) {image} nx ny nz nx,ny,nz = which periodic image of the simulation box the atom is in @@ -138,26 +147,31 @@ the orientation of a particular atom is the same, regardless of how many processors are being used. Keyword {quat} uses the specified values to create a quaternion -(4-vector) that represents the orientation of the selected atoms. -Note that particles defined by "atom_style ellipsoid"_atom_style.html -have 3 shape parameters. The 3 values must be non-zero for each -particle set by this command. They are used to specify the aspect -ratios of an ellipsoidal particle, which is oriented by default with -its x-axis along the simulation box's x-axis, and similarly for y and -z. If this body is rotated (via the right-hand rule) by an angle -theta around a unit rotation vector (a,b,c), then the quaternion that -represents its new orientation is given by (cos(theta/2), -a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). The theta and a,b,c -values are the arguments to the {quat} keyword. LAMMPS normalizes the -quaternion in case (a,b,c) was not specified as a unit vector. For 2d -systems, the a,b,c values are ignored, since a rotation vector of -(0,0,1) is the only valid choice. +(4-vector) that represents the orientation of the selected atoms. The +particles must be ellipsoids as defined by the "atom_style +ellipsoid"_atom_style.html command or triangles as defined by the +"atom_style tri"_atom_style.html command. Note that particles defined +by "atom_style ellipsoid"_atom_style.html have 3 shape parameters. +The 3 values must be non-zero for each particle set by this command. +They are used to specify the aspect ratios of an ellipsoidal particle, +which is oriented by default with its x-axis along the simulation +box's x-axis, and similarly for y and z. If this body is rotated (via +the right-hand rule) by an angle theta around a unit rotation vector +(a,b,c), then the quaternion that represents its new orientation is +given by (cos(theta/2), a*sin(theta/2), b*sin(theta/2), +c*sin(theta/2)). The theta and a,b,c values are the arguments to the +{quat} keyword. LAMMPS normalizes the quaternion in case (a,b,c) was +not specified as a unit vector. For 2d systems, the a,b,c values are +ignored, since a rotation vector of (0,0,1) is the only valid choice. Keyword {quat/random} randomizes the orientation of the quaternion of -the selected atoms. Random numbers are used in such a way that the -orientation of a particular atom is the same, regardless of how many -processors are being used. For 2d systems, only orientations in the -xy plane are generated. As with keyword {quat}, the 3 shape values +the selected atoms. The particles must be ellipsoids as defined by +the "atom_style ellipsoid"_atom_style.html command or triangles as +defined by the "atom_style tri"_atom_style.html command. Random +numbers are used in such a way that the orientation of a particular +atom is the same, regardless of how many processors are being used. +For 2d systems, only orientations in the xy plane are generated. As +with keyword {quat}, for ellipsoidal particles, the 3 shape values must be non-zero for each particle set by this command. Keyword {diameter} sets the size of the selected atoms. The particles @@ -169,7 +183,7 @@ defined with a density, e.g. via the "read_data"_read_data.html command. Keyword {shape} sets the size and shape of the selected atoms. The -particles must be aspherical ellipsoids as defined by the "atom_style +particles must be ellipsoids as defined by the "atom_style ellipsoid"_atom_style.html command. The {Sx}, {Sy}, {Sz} settings are the 3 diameters of the ellipsoid in each direction. All 3 can be set to the same value, which means the ellipsoid is effectively a sphere. @@ -178,20 +192,60 @@ treated as a point particle. Note that this command does not adjust the particle mass, even if it was defined with a density, e.g. via the "read_data"_read_data.html command. +Keyword {length} sets the length of selected atoms. The particles +must be line segments as defined by the "atom_style +line"_atom_style.html command. If the specified value is non-zero the +line segment is (re)set to a length = the specified value, centered +around the particle position, with an orientation along the x-axis. +If the specified value is 0.0, the particle will become a point +particle. Note that this command does not adjust the particle mass, +even if it was defined with a density, e.g. via the +"read_data"_read_data.html command. + +Keyword {tri} sets the size of selected atoms. The particles must be +triangles as defined by the "atom_style tri"_atom_style.html command. +If the specified value is non-zero the triangle is (re)set to be an +equilateral triangle in the xy plane with side length = the specified +value, with a centroid at the particle position, with its base +parallel to the x axis, and the y-axis running from the center of the +base to the top point of the triangle. If the specified value is 0.0, +the particle will become a point particle. Note that this command +does not adjust the particle mass, even if it was defined with a +density, e.g. via the "read_data"_read_data.html command. + +Keyword {theta} sets the orientation of selected atoms. The particles +must be line segments as defined by the "atom_style +line"_atom_style.html command. The specified value is used to set the +orientation angle of the line segments with respect to the x axis. + +Keyword {angmom} sets the angular momentum of selected atoms. The +particles must be ellipsoids as defined by the "atom_style +ellipsoid"_atom_style.html command or triangles as defined by the +"atom_style tri"_atom_style.html command. The angular momentum vector +of the particles is set to the 3 specified components. + Keyword {mass} sets the mass of all selected particles. The particles must have a per-atom mass attribute, as defined by the "atom_style"_atom_style.html command. See the "mass" command for how to set mass values on a per-type basis. -Keyword {density} sets the mass of all selected particles. The -particles must have a per-atom mass attribute, as defined by the -"atom_style"_atom_style.html command. See the "mass" command for how -to set mass values on a per-type basis. If the atom has a radius -attribute (see "atom_style sphere"_atom_style.html) and its radius is -non-zero, its mass is set from the density and particle volume. The -same is true if the atom has a shape attribute (see "atom_style -ellipsoid"_atom_style.html) and its 3 shape parameters are non-zero. -Otherwise the mass is set to the density value directly. +Keyword {density} also sets the mass of all selected particles, but in +a different way. The particles must have a per-atom mass attribute, +as defined by the "atom_style"_atom_style.html command. If the atom +has a radius attribute (see "atom_style sphere"_atom_style.html) and +its radius is non-zero, its mass is set from the density and particle +volume. If the atom has a shape attribute (see "atom_style +ellipsoid"_atom_style.html) and its 3 shape parameters are non-zero, +then its mass is set from the density and particle volume. If the +atom has a length attribute (see "atom_style line"_atom_style.html) +and its length is non-zero, then its mass is set from the density and +line segment length (the input density is assumed to be in +mass/distance units). If the atom has an area attribute (see +"atom_style tri"_atom_style.html) and its area is non-zero, then its +mass is set from the density and triangle area (the input density is +assumed to be in mass/distance^2 units). If none of these cases are +valid, then the mass is set to the density value directly (the input +density is assumed to be in mass units). Keyword {volume} sets the volume of all selected particles. Currently, only the "atom_style peri"_atom_style.html command defines diff --git a/examples/README b/examples/README index ffad2e66c5..814497cf81 100644 --- a/examples/README +++ b/examples/README @@ -29,6 +29,7 @@ colloid: big colloid particles in a small particle solvent, 2d system comb: models using the COMB potential crack: crack propagation in a 2d solid dipole: point dipolar particles, 2d system +dreiding: methanol via Dreiding FF eim: NaCl using the EIM potential ellipse: ellipsoidal particles in spherical solvent, 2d system flow: Couette and Poiseuille flow in a 2d channel diff --git a/examples/dreiding/README b/examples/dreiding/README new file mode 100644 index 0000000000..351f7e9e5c --- /dev/null +++ b/examples/dreiding/README @@ -0,0 +1,5 @@ +The LAMMPS input script and data file were built to +match the Cerius Dreiding files included +in this directory (ch3oh.box.*) so that you +can compare LAMMPS output to a Dreiding implementation +in the Cerius code. diff --git a/examples/dreiding/ch3oh.box.dreiding.bgf b/examples/dreiding/ch3oh.box.dreiding.bgf new file mode 100644 index 0000000000..b9431153aa --- /dev/null +++ b/examples/dreiding/ch3oh.box.dreiding.bgf @@ -0,0 +1,780 @@ +XTLGRF 200 +DESCRP Model6 +REMARK BGF file created by Cerius2 +FORCEFIELD DREIDING +PERIOD 111 +AXES ZYX +SGNAME P 1 1 1 +CRYSTX 19.99689 19.12816 19.46971 90.00000 90.00000 90.00000 +CELLS -1 1 -1 1 -1 1 +FORMAT ATOM (a6,1x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5, i3,i2,1x,f8.5) +HETATM 1 C1 RES A 444 9.75768 9.43603 9.44978 C_3 4 0 0.03193 +HETATM 2 O2 RES A 444 9.07001 9.89252 10.61030 O_3 2 2 -0.39965 +HETATM 3 H3 RES A 444 9.56169 8.37372 9.30573 H_ 1 0 0.05269 +HETATM 4 H4 RES A 444 9.40633 9.98872 8.57739 H_ 1 0 0.05269 +HETATM 5 H5 RES A 444 10.83081 9.58873 9.56849 H_ 1 0 0.05269 +HETATM 6 H6 RES A 444 9.28861 10.84826 10.67569 H___A 1 0 0.20964 +HETATM 7 C7 RES A 444 7.87790 6.57305 4.37926 C_3 4 0 0.03193 +HETATM 8 O8 RES A 444 9.21046 6.55811 3.88167 O_3 2 2 -0.39965 +HETATM 9 H9 RES A 444 7.42565 7.54437 4.17519 H_ 1 0 0.05269 +HETATM 10 H10 RES A 444 7.28908 5.79550 3.89029 H_ 1 0 0.05269 +HETATM 11 H11 RES A 444 7.88159 6.39628 5.45605 H_ 1 0 0.05269 +HETATM 12 H12 RES A 444 9.55621 5.66386 4.09964 H___A 1 0 0.20964 +HETATM 13 C13 RES A 444 19.38728 8.01844 0.29841 C_3 4 0 0.03193 +HETATM 14 O14 RES A 444 18.30059 8.67235 0.94403 O_3 2 2 -0.39965 +HETATM 15 H15 RES A 444 20.09420 7.66052 1.04704 H_ 1 0 0.05269 +HETATM 16 H16 RES A 444 19.01558 7.17130 -0.27928 H_ 1 0 0.05269 +HETATM 17 H17 RES A 444 19.89453 8.71684 -0.36839 H_ 1 0 0.05269 +HETATM 18 H18 RES A 444 17.72537 8.98355 0.21436 H___A 1 0 0.20964 +HETATM 19 C19 RES A 444 3.43963 14.29741 12.62221 C_3 4 0 0.03193 +HETATM 20 O20 RES A 444 3.07671 15.61822 12.23631 O_3 2 2 -0.39965 +HETATM 21 H21 RES A 444 4.27302 14.34187 13.32349 H_ 1 0 0.05269 +HETATM 22 H22 RES A 444 2.59308 13.81008 13.10508 H_ 1 0 0.05269 +HETATM 23 H23 RES A 444 3.73991 13.72415 11.74356 H_ 1 0 0.05269 +HETATM 24 H24 RES A 444 2.32966 15.52033 11.61130 H___A 1 0 0.20964 +HETATM 25 C25 RES A 444 16.06751 17.84957 14.39706 C_3 4 0 0.03193 +HETATM 26 O26 RES A 444 15.98970 19.07282 15.11734 O_3 2 2 -0.39965 +HETATM 27 H27 RES A 444 16.77526 17.18402 14.89204 H_ 1 0 0.05269 +HETATM 28 H28 RES A 444 15.08510 17.37867 14.36938 H_ 1 0 0.05269 +HETATM 29 H29 RES A 444 16.40684 18.04085 13.37809 H_ 1 0 0.05269 +HETATM 30 H30 RES A 444 15.35997 19.62900 14.61094 H___A 1 0 0.20964 +HETATM 31 C31 RES A 444 5.61540 13.90261 0.28024 C_3 4 0 0.03193 +HETATM 32 O32 RES A 444 6.96329 14.33980 0.39819 O_3 2 2 -0.39965 +HETATM 33 H33 RES A 444 5.39381 13.18200 1.06831 H_ 1 0 0.05269 +HETATM 34 H34 RES A 444 4.93854 14.75467 0.36989 H_ 1 0 0.05269 +HETATM 35 H35 RES A 444 5.46825 13.42632 -0.68848 H_ 1 0 0.05269 +HETATM 36 H36 RES A 444 7.08381 14.99923 -0.31851 H___A 1 0 0.20964 +HETATM 37 C37 RES A 444 10.38444 13.74977 1.74423 C_3 4 0 0.03193 +HETATM 38 O38 RES A 444 10.34865 13.00890 2.96031 O_3 2 2 -0.39965 +HETATM 39 H39 RES A 444 11.31498 14.30998 1.68756 H_ 1 0 0.05269 +HETATM 40 H40 RES A 444 10.32135 13.06875 0.89580 H_ 1 0 0.05269 +HETATM 41 H41 RES A 444 9.54190 14.44190 1.71309 H_ 1 0 0.05269 +HETATM 42 H42 RES A 444 9.45315 12.60486 2.98815 H___A 1 0 0.20964 +HETATM 43 C43 RES A 444 2.71877 -0.19852 13.91482 C_3 4 0 0.03193 +HETATM 44 O44 RES A 444 2.55981 1.00656 13.16980 O_3 2 2 -0.39965 +HETATM 45 H45 RES A 444 3.42887 -0.85053 13.40421 H_ 1 0 0.05269 +HETATM 46 H46 RES A 444 3.09835 0.02977 14.91227 H_ 1 0 0.05269 +HETATM 47 H47 RES A 444 1.76062 -0.71177 13.99933 H_ 1 0 0.05269 +HETATM 48 H48 RES A 444 1.92580 1.55260 13.68058 H___A 1 0 0.20964 +HETATM 49 C49 RES A 444 12.86271 12.87291 9.10254 C_3 4 0 0.03193 +HETATM 50 O50 RES A 444 12.72964 12.19590 7.85730 O_3 2 2 -0.39965 +HETATM 51 H51 RES A 444 11.91715 12.83126 9.64447 H_ 1 0 0.05269 +HETATM 52 H52 RES A 444 13.63913 12.39659 9.70188 H_ 1 0 0.05269 +HETATM 53 H53 RES A 444 13.12955 13.91577 8.92585 H_ 1 0 0.05269 +HETATM 54 H54 RES A 444 13.60640 12.28637 7.42000 H___A 1 0 0.20964 +HETATM 55 C55 RES A 444 0.91345 1.84436 7.21758 C_3 4 0 0.03193 +HETATM 56 O56 RES A 444 0.16704 0.83109 7.88260 O_3 2 2 -0.39965 +HETATM 57 H57 RES A 444 1.73149 1.39473 6.65448 H_ 1 0 0.05269 +HETATM 58 H58 RES A 444 0.25949 2.38287 6.53090 H_ 1 0 0.05269 +HETATM 59 H59 RES A 444 1.31674 2.54212 7.95173 H_ 1 0 0.05269 +HETATM 60 H60 RES A 444 0.79209 0.41480 8.51642 H___A 1 0 0.20964 +HETATM 61 C61 RES A 444 3.28235 16.40235 6.34784 C_3 4 0 0.03193 +HETATM 62 O62 RES A 444 4.40446 15.86811 5.64397 O_3 2 2 -0.39965 +HETATM 63 H63 RES A 444 3.52775 16.47384 7.40940 H_ 1 0 0.05269 +HETATM 64 H64 RES A 444 3.04852 17.39543 5.96551 H_ 1 0 0.05269 +HETATM 65 H65 RES A 444 2.41989 15.75077 6.22278 H_ 1 0 0.05269 +HETATM 66 H66 RES A 444 4.15040 15.88018 4.69552 H___A 1 0 0.20964 +HETATM 67 C67 RES A 444 14.28685 11.84833 2.69644 C_3 4 0 0.03193 +HETATM 68 O68 RES A 444 14.47540 12.00775 4.09802 O_3 2 2 -0.39965 +HETATM 69 H69 RES A 444 15.22519 11.52503 2.24449 H_ 1 0 0.05269 +HETATM 70 H70 RES A 444 13.51978 11.09713 2.50925 H_ 1 0 0.05269 +HETATM 71 H71 RES A 444 13.98187 12.79680 2.25228 H_ 1 0 0.05269 +HETATM 72 H72 RES A 444 13.60420 12.29868 4.44979 H___A 1 0 0.20964 +HETATM 73 C73 RES A 444 3.74650 0.37490 9.28202 C_3 4 0 0.03193 +HETATM 74 O74 RES A 444 4.68624 1.26369 8.68537 O_3 2 2 -0.39965 +HETATM 75 H75 RES A 444 4.28178 -0.38700 9.84868 H_ 1 0 0.05269 +HETATM 76 H76 RES A 444 3.08874 0.92642 9.95440 H_ 1 0 0.05269 +HETATM 77 H77 RES A 444 3.15691 -0.10643 8.50276 H_ 1 0 0.05269 +HETATM 78 H78 RES A 444 4.15269 1.92251 8.18619 H___A 1 0 0.20964 +HETATM 79 C79 RES A 444 17.93191 1.98830 17.28592 C_3 4 0 0.03193 +HETATM 80 O80 RES A 444 16.68990 1.36769 17.60090 O_3 2 2 -0.39965 +HETATM 81 H81 RES A 444 18.23740 2.63433 18.10865 H_ 1 0 0.05269 +HETATM 82 H82 RES A 444 18.69345 1.22519 17.12938 H_ 1 0 0.05269 +HETATM 83 H83 RES A 444 17.82727 2.59026 16.38313 H_ 1 0 0.05269 +HETATM 84 H84 RES A 444 16.45659 0.83462 16.81232 H___A 1 0 0.20964 +HETATM 85 C85 RES A 444 4.61466 10.52979 17.10957 C_3 4 0 0.03193 +HETATM 86 O86 RES A 444 3.62035 11.42538 17.60198 O_3 2 2 -0.39965 +HETATM 87 H87 RES A 444 5.60177 10.98718 17.19552 H_ 1 0 0.05269 +HETATM 88 H88 RES A 444 4.60514 9.60666 17.68872 H_ 1 0 0.05269 +HETATM 89 H89 RES A 444 4.42040 10.30112 16.06086 H_ 1 0 0.05269 +HETATM 90 H90 RES A 444 2.76200 10.96432 17.46823 H___A 1 0 0.20964 +HETATM 91 C91 RES A 444 4.21479 2.76452 1.93621 C_3 4 0 0.03193 +HETATM 92 O92 RES A 444 3.45640 2.43822 3.09183 O_3 2 2 -0.39965 +HETATM 93 H93 RES A 444 5.15561 3.22498 2.23935 H_ 1 0 0.05269 +HETATM 94 H94 RES A 444 4.42333 1.85922 1.36296 H_ 1 0 0.05269 +HETATM 95 H95 RES A 444 3.65868 3.46500 1.31342 H_ 1 0 0.05269 +HETATM 96 H96 RES A 444 2.68968 1.92747 2.75853 H___A 1 0 0.20964 +HETATM 97 C97 RES A 444 2.10781 10.76856 1.36312 C_3 4 0 0.03193 +HETATM 98 O98 RES A 444 0.80698 11.27394 1.07892 O_3 2 2 -0.39965 +HETATM 99 H99 RES A 444 2.85114 11.53660 1.14272 H_ 1 0 0.05269 +HETATM 100 H100 RES A 444 2.17873 10.49350 2.41651 H_ 1 0 0.05269 +HETATM 101 H101 RES A 444 2.31220 9.89096 0.74802 H_ 1 0 0.05269 +HETATM 102 H102 RES A 444 0.18009 10.55168 1.30975 H___A 1 0 0.20964 +HETATM 103 C103 RES A 444 16.26093 8.92927 6.57643 C_3 4 0 0.03193 +HETATM 104 O104 RES A 444 15.77968 8.06983 7.60177 O_3 2 2 -0.39965 +HETATM 105 H105 RES A 444 17.30509 9.17300 6.76897 H_ 1 0 0.05269 +HETATM 106 H106 RES A 444 16.18069 8.42876 5.61195 H_ 1 0 0.05269 +HETATM 107 H107 RES A 444 15.67380 9.84869 6.55835 H_ 1 0 0.05269 +HETATM 108 H108 RES A 444 14.84042 7.91008 7.37720 H___A 1 0 0.20964 +HETATM 109 C109 RES A 444 17.80004 2.06792 1.87371 C_3 4 0 0.03193 +HETATM 110 O110 RES A 444 18.48862 0.99081 1.24012 O_3 2 2 -0.39965 +HETATM 111 H111 RES A 444 18.23871 2.25534 2.85453 H_ 1 0 0.05269 +HETATM 112 H112 RES A 444 17.87937 2.96817 1.26859 H_ 1 0 0.05269 +HETATM 113 H113 RES A 444 16.74643 1.80633 1.99693 H_ 1 0 0.05269 +HETATM 114 H114 RES A 444 18.02202 0.85350 0.38356 H___A 1 0 0.20964 +HETATM 115 C115 RES A 444 13.75521 14.57173 15.42181 C_3 4 0 0.03193 +HETATM 116 O116 RES A 444 12.73183 15.48504 15.80455 O_3 2 2 -0.39965 +HETATM 117 H117 RES A 444 14.51862 14.53760 16.20019 H_ 1 0 0.05269 +HETATM 118 H118 RES A 444 13.33164 13.57618 15.29114 H_ 1 0 0.05269 +HETATM 119 H119 RES A 444 14.21175 14.89091 14.48437 H_ 1 0 0.05269 +HETATM 120 H120 RES A 444 12.11746 15.52768 15.03694 H___A 1 0 0.20964 +HETATM 121 C121 RES A 444 6.22569 16.46321 11.49168 C_3 4 0 0.03193 +HETATM 122 O122 RES A 444 7.37834 15.65849 11.27192 O_3 2 2 -0.39965 +HETATM 123 H123 RES A 444 6.47325 17.50688 11.31115 H_ 1 0 0.05269 +HETATM 124 H124 RES A 444 5.42639 16.16714 10.80967 H_ 1 0 0.05269 +HETATM 125 H125 RES A 444 5.88670 16.35324 12.52283 H_ 1 0 0.05269 +HETATM 126 H126 RES A 444 7.09224 14.73066 11.41776 H___A 1 0 0.20964 +HETATM 127 C127 RES A 444 20.01012 9.33317 4.86657 C_3 4 0 0.03193 +HETATM 128 O128 RES A 444 19.63827 8.14994 5.56401 O_3 2 2 -0.39965 +HETATM 129 H129 RES A 444 20.82510 9.82112 5.40128 H_ 1 0 0.05269 +HETATM 130 H130 RES A 444 20.34186 9.07963 3.85908 H_ 1 0 0.05269 +HETATM 131 H131 RES A 444 19.16051 10.01349 4.80673 H_ 1 0 0.05269 +HETATM 132 H132 RES A 444 18.86130 7.79949 5.07585 H___A 1 0 0.20964 +HETATM 133 C133 RES A 444 5.99486 1.97634 5.72513 C_3 4 0 0.03193 +HETATM 134 O134 RES A 444 6.74021 3.13466 6.08586 O_3 2 2 -0.39965 +HETATM 135 H135 RES A 444 4.92875 2.19578 5.79288 H_ 1 0 0.05269 +HETATM 136 H136 RES A 444 6.23376 1.68432 4.70221 H_ 1 0 0.05269 +HETATM 137 H137 RES A 444 6.23815 1.15441 6.40034 H_ 1 0 0.05269 +HETATM 138 H138 RES A 444 7.67684 2.83917 6.07790 H___A 1 0 0.20964 +HETATM 139 C139 RES A 444 13.03835 7.12913 5.28770 C_3 4 0 0.03193 +HETATM 140 O140 RES A 444 13.02644 7.55487 6.64544 O_3 2 2 -0.39965 +HETATM 141 H141 RES A 444 12.06949 6.70203 5.02747 H_ 1 0 0.05269 +HETATM 142 H142 RES A 444 13.24117 7.98172 4.63978 H_ 1 0 0.05269 +HETATM 143 H143 RES A 444 13.81531 6.37647 5.14697 H_ 1 0 0.05269 +HETATM 144 H144 RES A 444 12.38966 8.29858 6.65964 H___A 1 0 0.20964 +HETATM 145 C145 RES A 444 10.64649 1.42163 6.99575 C_3 4 0 0.03193 +HETATM 146 O146 RES A 444 11.32932 1.55767 8.23581 O_3 2 2 -0.39965 +HETATM 147 H147 RES A 444 9.77461 0.78340 7.13967 H_ 1 0 0.05269 +HETATM 148 H148 RES A 444 10.32031 2.40213 6.64261 H_ 1 0 0.05269 +HETATM 149 H149 RES A 444 11.30461 0.96891 6.25436 H_ 1 0 0.05269 +HETATM 150 H150 RES A 444 12.13048 2.09412 8.04749 H___A 1 0 0.20964 +HETATM 151 C151 RES A 444 7.70974 10.56643 0.43745 C_3 4 0 0.03193 +HETATM 152 O152 RES A 444 6.69643 10.25499 1.38817 O_3 2 2 -0.39965 +HETATM 153 H153 RES A 444 8.59868 10.91732 0.96199 H_ 1 0 0.05269 +HETATM 154 H154 RES A 444 7.96121 9.67471 -0.13665 H_ 1 0 0.05269 +HETATM 155 H155 RES A 444 7.36428 11.34806 -0.24011 H_ 1 0 0.05269 +HETATM 156 H156 RES A 444 5.94241 9.89154 0.87302 H___A 1 0 0.20964 +HETATM 157 C157 RES A 444 12.78344 1.18067 14.16301 C_3 4 0 0.03193 +HETATM 158 O158 RES A 444 14.01647 1.62010 13.60417 O_3 2 2 -0.39965 +HETATM 159 H159 RES A 444 12.98217 0.47776 14.97222 H_ 1 0 0.05269 +HETATM 160 H160 RES A 444 12.23227 2.03435 14.55662 H_ 1 0 0.05269 +HETATM 161 H161 RES A 444 12.18352 0.68832 13.39874 H_ 1 0 0.05269 +HETATM 162 H162 RES A 444 13.77530 2.26070 12.89474 H___A 1 0 0.20964 +HETATM 163 C163 RES A 444 16.94139 17.42253 1.05686 C_3 4 0 0.03193 +HETATM 164 O164 RES A 444 16.08424 16.29569 1.04946 O_3 2 2 -0.39965 +HETATM 165 H165 RES A 444 17.18791 17.69368 0.02960 H_ 1 0 0.05269 +HETATM 166 H166 RES A 444 16.43795 18.25970 1.54236 H_ 1 0 0.05269 +HETATM 167 H167 RES A 444 17.85566 17.18021 1.60025 H_ 1 0 0.05269 +HETATM 168 H168 RES A 444 15.85827 16.14412 1.99459 H___A 1 0 0.20964 +HETATM 169 C169 RES A 444 12.48878 18.07306 2.58158 C_3 4 0 0.03193 +HETATM 170 O170 RES A 444 13.76343 18.70451 2.65479 O_3 2 2 -0.39965 +HETATM 171 H171 RES A 444 12.02971 18.30966 1.62310 H_ 1 0 0.05269 +HETATM 172 H172 RES A 444 12.61189 16.99304 2.67149 H_ 1 0 0.05269 +HETATM 173 H173 RES A 444 11.85062 18.43623 3.38623 H_ 1 0 0.05269 +HETATM 174 H174 RES A 444 14.05960 18.54980 3.57438 H___A 1 0 0.20964 +HETATM 175 C175 RES A 444 19.92937 14.32320 3.09954 C_3 4 0 0.03193 +HETATM 176 O176 RES A 444 20.47921 14.98239 4.23349 O_3 2 2 -0.39965 +HETATM 177 H177 RES A 444 19.06424 14.88021 2.74247 H_ 1 0 0.05269 +HETATM 178 H178 RES A 444 20.67424 14.26863 2.30532 H_ 1 0 0.05269 +HETATM 179 H179 RES A 444 19.62003 13.31457 3.37662 H_ 1 0 0.05269 +HETATM 180 H180 RES A 444 21.24382 14.42340 4.50083 H___A 1 0 0.20964 +HETATM 181 C181 RES A 444 10.63009 10.62036 5.48247 C_3 4 0 0.03193 +HETATM 182 O182 RES A 444 11.32080 9.96459 6.53930 O_3 2 2 -0.39965 +HETATM 183 H183 RES A 444 9.97896 9.90801 4.97371 H_ 1 0 0.05269 +HETATM 184 H184 RES A 444 10.02580 11.43533 5.88411 H_ 1 0 0.05269 +HETATM 185 H185 RES A 444 11.34799 11.02578 4.76860 H_ 1 0 0.05269 +HETATM 186 H186 RES A 444 11.85790 10.67095 6.95281 H___A 1 0 0.20964 +HETATM 187 C187 RES A 444 15.65699 9.09727 17.99408 C_3 4 0 0.03193 +HETATM 188 O188 RES A 444 16.90142 9.78939 17.98916 O_3 2 2 -0.39965 +HETATM 189 H189 RES A 444 15.04412 9.44428 18.82685 H_ 1 0 0.05269 +HETATM 190 H190 RES A 444 15.12611 9.28242 17.05809 H_ 1 0 0.05269 +HETATM 191 H191 RES A 444 15.82887 8.02576 18.10423 H_ 1 0 0.05269 +HETATM 192 H192 RES A 444 17.40700 9.38003 17.24481 H___A 1 0 0.20964 +HETATM 193 C193 RES A 444 17.18063 5.09511 5.97377 C_3 4 0 0.03193 +HETATM 194 O194 RES A 444 17.00699 3.69621 6.16625 O_3 2 2 -0.39965 +HETATM 195 H195 RES A 444 16.80087 5.38050 4.99222 H_ 1 0 0.05269 +HETATM 196 H196 RES A 444 16.63290 5.63866 6.74297 H_ 1 0 0.05269 +HETATM 197 H197 RES A 444 18.23947 5.34654 6.03632 H_ 1 0 0.05269 +HETATM 198 H198 RES A 444 17.37922 3.51369 7.05728 H___A 1 0 0.20964 +HETATM 199 C199 RES A 444 9.27176 16.96360 18.60348 C_3 4 0 0.03193 +HETATM 200 O200 RES A 444 10.16048 17.88001 19.23027 O_3 2 2 -0.39965 +HETATM 201 H201 RES A 444 8.24372 17.25233 18.82182 H_ 1 0 0.05269 +HETATM 202 H202 RES A 444 9.42846 16.97594 17.52377 H_ 1 0 0.05269 +HETATM 203 H203 RES A 444 9.45162 15.95835 18.98512 H_ 1 0 0.05269 +HETATM 204 H204 RES A 444 11.05433 17.57777 18.98374 H___A 1 0 0.20964 +HETATM 205 C205 RES A 444 19.02698 11.32629 8.74382 C_3 4 0 0.03193 +HETATM 206 O206 RES A 444 19.55395 11.57496 7.44476 O_3 2 2 -0.39965 +HETATM 207 H207 RES A 444 19.84306 11.28874 9.46486 H_ 1 0 0.05269 +HETATM 208 H208 RES A 444 18.34041 12.12651 9.02172 H_ 1 0 0.05269 +HETATM 209 H209 RES A 444 18.49941 10.37268 8.75573 H_ 1 0 0.05269 +HETATM 210 H210 RES A 444 18.77484 11.55877 6.84653 H___A 1 0 0.20964 +HETATM 211 C211 RES A 444 13.70984 17.91381 18.18096 C_3 4 0 0.03193 +HETATM 212 O212 RES A 444 12.78082 16.86629 18.42949 O_3 2 2 -0.39965 +HETATM 213 H213 RES A 444 14.65264 17.49419 17.82801 H_ 1 0 0.05269 +HETATM 214 H214 RES A 444 13.30579 18.58561 17.42320 H_ 1 0 0.05269 +HETATM 215 H215 RES A 444 13.88737 18.47185 19.10049 H_ 1 0 0.05269 +HETATM 216 H216 RES A 444 12.70938 16.39241 17.57615 H___A 1 0 0.20964 +HETATM 217 C217 RES A 444 7.96084 1.88854 9.90132 C_3 4 0 0.03193 +HETATM 218 O218 RES A 444 7.16836 0.76877 10.27166 O_3 2 2 -0.39965 +HETATM 219 H219 RES A 444 8.08701 1.90679 8.82000 H_ 1 0 0.05269 +HETATM 220 H220 RES A 444 7.47244 2.80930 10.22050 H_ 1 0 0.05269 +HETATM 221 H221 RES A 444 8.93667 1.81039 10.37952 H_ 1 0 0.05269 +HETATM 222 H222 RES A 444 6.33219 0.87991 9.77220 H___A 1 0 0.20964 +HETATM 223 C223 RES A 444 8.67989 16.70958 5.83790 C_3 4 0 0.03193 +HETATM 224 O224 RES A 444 8.12024 17.60224 6.79460 O_3 2 2 -0.39965 +HETATM 225 H225 RES A 444 8.09228 16.75013 4.91967 H_ 1 0 0.05269 +HETATM 226 H226 RES A 444 9.70728 17.00048 5.62151 H_ 1 0 0.05269 +HETATM 227 H227 RES A 444 8.66415 15.69153 6.22812 H_ 1 0 0.05269 +HETATM 228 H228 RES A 444 8.61953 17.44038 7.62546 H___A 1 0 0.20964 +HETATM 229 C229 RES A 444 8.92912 4.00904 0.50900 C_3 4 0 0.03193 +HETATM 230 O230 RES A 444 8.96759 5.27857 -0.13058 O_3 2 2 -0.39965 +HETATM 231 H231 RES A 444 8.33969 4.08141 1.42278 H_ 1 0 0.05269 +HETATM 232 H232 RES A 444 8.47682 3.27429 -0.15833 H_ 1 0 0.05269 +HETATM 233 H233 RES A 444 9.94193 3.69036 0.75961 H_ 1 0 0.05269 +HETATM 234 H234 RES A 444 9.53405 5.14064 -0.92363 H___A 1 0 0.20964 +HETATM 235 C235 RES A 444 14.12006 6.78048 11.59632 C_3 4 0 0.03193 +HETATM 236 O236 RES A 444 13.07688 7.13628 10.69542 O_3 2 2 -0.39965 +HETATM 237 H237 RES A 444 14.86068 7.57932 11.63302 H_ 1 0 0.05269 +HETATM 238 H238 RES A 444 13.70582 6.62813 12.59405 H_ 1 0 0.05269 +HETATM 239 H239 RES A 444 14.60290 5.86276 11.26001 H_ 1 0 0.05269 +HETATM 240 H240 RES A 444 12.46641 6.36815 10.68540 H___A 1 0 0.20964 +HETATM 241 C241 RES A 444 11.17366 12.60541 17.35410 C_3 4 0 0.03193 +HETATM 242 O242 RES A 444 11.02139 13.96786 17.73395 O_3 2 2 -0.39965 +HETATM 243 H243 RES A 444 10.47704 11.99021 17.92352 H_ 1 0 0.05269 +HETATM 244 H244 RES A 444 10.96097 12.49402 16.29011 H_ 1 0 0.05269 +HETATM 245 H245 RES A 444 12.19388 12.27752 17.55780 H_ 1 0 0.05269 +HETATM 246 H246 RES A 444 11.62997 14.46572 17.15437 H___A 1 0 0.20964 +HETATM 247 C247 RES A 444 13.59375 17.68257 6.60725 C_3 4 0 0.03193 +HETATM 248 O248 RES A 444 14.41796 18.19915 5.56896 O_3 2 2 -0.39965 +HETATM 249 H249 RES A 444 12.56750 17.59958 6.25257 H_ 1 0 0.05269 +HETATM 250 H250 RES A 444 13.95140 16.69610 6.90350 H_ 1 0 0.05269 +HETATM 251 H251 RES A 444 13.62441 18.35441 7.46523 H_ 1 0 0.05269 +HETATM 252 H252 RES A 444 15.31701 18.26489 5.96089 H___A 1 0 0.20964 +HETATM 253 C253 RES A 444 5.00550 8.70879 7.93082 C_3 4 0 0.03193 +HETATM 254 O254 RES A 444 5.30633 7.53730 7.17920 O_3 2 2 -0.39965 +HETATM 255 H255 RES A 444 3.92410 8.80228 8.03546 H_ 1 0 0.05269 +HETATM 256 H256 RES A 444 5.45973 8.64206 8.92134 H_ 1 0 0.05269 +HETATM 257 H257 RES A 444 5.39337 9.58812 7.41497 H_ 1 0 0.05269 +HETATM 258 H258 RES A 444 6.28240 7.52607 7.08649 H___A 1 0 0.20964 +HETATM 259 C259 RES A 444 19.22046 1.28969 13.91270 C_3 4 0 0.03193 +HETATM 260 O260 RES A 444 20.08805 2.12898 14.66921 O_3 2 2 -0.39965 +HETATM 261 H261 RES A 444 18.36269 1.87059 13.57299 H_ 1 0 0.05269 +HETATM 262 H262 RES A 444 19.74873 0.89208 13.04541 H_ 1 0 0.05269 +HETATM 263 H263 RES A 444 18.87095 0.46148 14.53042 H_ 1 0 0.05269 +HETATM 264 H264 RES A 444 20.73583 1.52580 15.09558 H___A 1 0 0.20964 +HETATM 265 C265 RES A 444 5.65052 5.42047 10.40141 C_3 4 0 0.03193 +HETATM 266 O266 RES A 444 6.43233 5.15576 11.55959 O_3 2 2 -0.39965 +HETATM 267 H267 RES A 444 4.77591 4.76790 10.40245 H_ 1 0 0.05269 +HETATM 268 H268 RES A 444 5.31750 6.45945 10.40208 H_ 1 0 0.05269 +HETATM 269 H269 RES A 444 6.23775 5.22771 9.50311 H_ 1 0 0.05269 +HETATM 270 H270 RES A 444 7.22334 5.73649 11.49818 H___A 1 0 0.20964 +HETATM 271 C271 RES A 444 13.28289 5.81639 20.26495 C_3 4 0 0.03193 +HETATM 272 O272 RES A 444 14.46108 5.91020 19.47306 O_3 2 2 -0.39965 +HETATM 273 H273 RES A 444 12.54449 6.53149 19.89956 H_ 1 0 0.05269 +HETATM 274 H274 RES A 444 12.86565 4.81041 20.20085 H_ 1 0 0.05269 +HETATM 275 H275 RES A 444 13.51599 6.04282 21.30628 H_ 1 0 0.05269 +HETATM 276 H276 RES A 444 15.06689 5.21681 19.82048 H___A 1 0 0.20964 +HETATM 277 C277 RES A 444 8.93119 18.18764 13.28407 C_3 4 0 0.03193 +HETATM 278 O278 RES A 444 7.83369 17.94987 14.15258 O_3 2 2 -0.39965 +HETATM 279 H279 RES A 444 8.62256 18.85058 12.47662 H_ 1 0 0.05269 +HETATM 280 H280 RES A 444 9.74951 18.65521 13.83984 H_ 1 0 0.05269 +HETATM 281 H281 RES A 444 9.27914 17.24313 12.85839 H_ 1 0 0.05269 +HETATM 282 H282 RES A 444 8.18034 17.33710 14.83873 H___A 1 0 0.20964 +HETATM 283 C283 RES A 444 5.79456 2.19968 17.80701 C_3 4 0 0.03193 +HETATM 284 O284 RES A 444 6.24133 2.96696 16.69489 O_3 2 2 -0.39965 +HETATM 285 H285 RES A 444 5.95925 2.76662 18.72146 H_ 1 0 0.05269 +HETATM 286 H286 RES A 444 4.73133 1.97951 17.70368 H_ 1 0 0.05269 +HETATM 287 H287 RES A 444 6.35360 1.26369 17.85787 H_ 1 0 0.05269 +HETATM 288 H288 RES A 444 6.11167 2.36984 15.93032 H___A 1 0 0.20964 +HETATM 289 C289 RES A 444 7.02257 8.31146 13.32419 C_3 4 0 0.03193 +HETATM 290 O290 RES A 444 6.81830 9.58617 13.92250 O_3 2 2 -0.39965 +HETATM 291 H291 RES A 444 6.70351 7.53159 14.01772 H_ 1 0 0.05269 +HETATM 292 H292 RES A 444 6.43819 8.23664 12.40602 H_ 1 0 0.05269 +HETATM 293 H293 RES A 444 8.08019 8.17829 13.09255 H_ 1 0 0.05269 +HETATM 294 H294 RES A 444 7.15181 10.23194 13.26245 H___A 1 0 0.20964 +HETATM 295 C295 RES A 444 14.02631 3.46938 16.96774 C_3 4 0 0.03193 +HETATM 296 O296 RES A 444 13.54366 2.24600 17.51611 O_3 2 2 -0.39965 +HETATM 297 H297 RES A 444 13.77498 3.53066 15.91013 H_ 1 0 0.05269 +HETATM 298 H298 RES A 444 13.56595 4.30739 17.48900 H_ 1 0 0.05269 +HETATM 299 H299 RES A 444 15.10861 3.52592 17.07904 H_ 1 0 0.05269 +HETATM 300 H300 RES A 444 13.94305 2.20406 18.41525 H___A 1 0 0.20964 +HETATM 301 C301 RES A 444 1.20831 18.57486 2.95108 C_3 4 0 0.03193 +HETATM 302 O302 RES A 444 1.22576 19.81993 2.26075 O_3 2 2 -0.39965 +HETATM 303 H303 RES A 444 0.55458 18.64320 3.82147 H_ 1 0 0.05269 +HETATM 304 H304 RES A 444 0.84728 17.78646 2.28798 H_ 1 0 0.05269 +HETATM 305 H305 RES A 444 2.21813 18.32995 3.28130 H_ 1 0 0.05269 +HETATM 306 H306 RES A 444 0.30364 19.97372 1.97883 H___A 1 0 0.20964 +HETATM 307 C307 RES A 444 13.27354 18.56828 10.67719 C_3 4 0 0.03193 +HETATM 308 O308 RES A 444 12.48821 17.54334 10.07841 O_3 2 2 -0.39965 +HETATM 309 H309 RES A 444 12.67535 19.47728 10.75867 H_ 1 0 0.05269 +HETATM 310 H310 RES A 444 13.59103 18.25289 11.67155 H_ 1 0 0.05269 +HETATM 311 H311 RES A 444 14.15208 18.77184 10.06448 H_ 1 0 0.05269 +HETATM 312 H312 RES A 444 13.09935 16.78781 9.93641 H___A 1 0 0.20964 +HETATM 313 C313 RES A 444 6.36730 14.29234 8.10345 C_3 4 0 0.03193 +HETATM 314 O314 RES A 444 6.40678 13.98673 6.71535 O_3 2 2 -0.39965 +HETATM 315 H315 RES A 444 5.36805 14.09806 8.49177 H_ 1 0 0.05269 +HETATM 316 H316 RES A 444 7.08832 13.66856 8.63166 H_ 1 0 0.05269 +HETATM 317 H317 RES A 444 6.61905 15.34196 8.25886 H_ 1 0 0.05269 +HETATM 318 H318 RES A 444 5.76587 14.60457 6.30951 H___A 1 0 0.20964 +HETATM 319 C319 RES A 444 2.65328 9.08063 11.58358 C_3 4 0 0.03193 +HETATM 320 O320 RES A 444 2.00217 9.04988 10.31818 O_3 2 2 -0.39965 +HETATM 321 H321 RES A 444 2.77179 8.06201 11.95511 H_ 1 0 0.05269 +HETATM 322 H322 RES A 444 3.63556 9.54427 11.48302 H_ 1 0 0.05269 +HETATM 323 H323 RES A 444 2.05382 9.65342 12.29226 H_ 1 0 0.05269 +HETATM 324 H324 RES A 444 1.90245 9.98881 10.05330 H___A 1 0 0.20964 +HETATM 325 C325 RES A 444 16.09537 13.47946 18.75299 C_3 4 0 0.03193 +HETATM 326 O326 RES A 444 15.35647 12.29789 19.02596 O_3 2 2 -0.39965 +HETATM 327 H327 RES A 444 15.44738 14.34606 18.88103 H_ 1 0 0.05269 +HETATM 328 H328 RES A 444 16.93959 13.54850 19.44072 H_ 1 0 0.05269 +HETATM 329 H329 RES A 444 16.46394 13.45617 17.72675 H_ 1 0 0.05269 +HETATM 330 H330 RES A 444 15.94172 11.56097 18.74998 H___A 1 0 0.20964 +HETATM 331 C331 RES A 444 5.36713 6.40841 19.02468 C_3 4 0 0.03193 +HETATM 332 O332 RES A 444 6.23337 6.92207 18.01801 O_3 2 2 -0.39965 +HETATM 333 H333 RES A 444 4.33549 6.65297 18.77623 H_ 1 0 0.05269 +HETATM 334 H334 RES A 444 5.47707 5.32425 19.08654 H_ 1 0 0.05269 +HETATM 335 H335 RES A 444 5.62819 6.85675 19.98559 H_ 1 0 0.05269 +HETATM 336 H336 RES A 444 7.13950 6.67949 18.31120 H___A 1 0 0.20964 +HETATM 337 C337 RES A 444 1.77513 13.81811 9.21198 C_3 4 0 0.03193 +HETATM 338 O338 RES A 444 0.83100 14.28966 10.16552 O_3 2 2 -0.39965 +HETATM 339 H339 RES A 444 1.29728 13.75593 8.23483 H_ 1 0 0.05269 +HETATM 340 H340 RES A 444 2.62178 14.50388 9.15673 H_ 1 0 0.05269 +HETATM 341 H341 RES A 444 2.12880 12.82836 9.50371 H_ 1 0 0.05269 +HETATM 342 H342 RES A 444 1.30194 14.30478 11.02173 H___A 1 0 0.20964 +HETATM 343 C343 RES A 444 21.59943 4.06368 17.75073 C_3 4 0 0.03193 +HETATM 344 O344 RES A 444 21.85233 3.04768 18.71336 O_3 2 2 -0.39965 +HETATM 345 H345 RES A 444 22.11092 3.81498 16.82008 H_ 1 0 0.05269 +HETATM 346 H346 RES A 444 20.52800 4.13659 17.56408 H_ 1 0 0.05269 +HETATM 347 H347 RES A 444 21.97071 5.01986 18.11886 H_ 1 0 0.05269 +HETATM 348 H348 RES A 444 21.40074 3.34325 19.53474 H___A 1 0 0.20964 +HETATM 349 C349 RES A 444 16.52622 4.73908 13.63762 C_3 4 0 0.03193 +HETATM 350 O350 RES A 444 15.55282 5.45454 14.38889 O_3 2 2 -0.39965 +HETATM 351 H351 RES A 444 16.03370 3.96708 13.04616 H_ 1 0 0.05269 +HETATM 352 H352 RES A 444 17.05262 5.42291 12.96909 H_ 1 0 0.05269 +HETATM 353 H353 RES A 444 17.24076 4.27126 14.31456 H_ 1 0 0.05269 +HETATM 354 H354 RES A 444 16.06701 6.07053 14.95693 H___A 1 0 0.20964 +HETATM 355 C355 RES A 444 20.20141 14.20302 18.50889 C_3 4 0 0.03193 +HETATM 356 O356 RES A 444 21.44729 13.78288 19.04009 O_3 2 2 -0.39965 +HETATM 357 H357 RES A 444 20.32931 15.13613 17.95996 H_ 1 0 0.05269 +HETATM 358 H358 RES A 444 19.81275 13.43791 17.83324 H_ 1 0 0.05269 +HETATM 359 H359 RES A 444 19.48848 14.36395 19.32079 H_ 1 0 0.05269 +HETATM 360 H360 RES A 444 21.25026 12.96615 19.54627 H___A 1 0 0.20964 +HETATM 361 C361 RES A 444 3.32298 14.94425 16.50422 C_3 4 0 0.03193 +HETATM 362 O362 RES A 444 4.38694 14.00670 16.37303 O_3 2 2 -0.39965 +HETATM 363 H363 RES A 444 3.54498 15.83135 15.91086 H_ 1 0 0.05269 +HETATM 364 H364 RES A 444 2.39143 14.50263 16.15017 H_ 1 0 0.05269 +HETATM 365 H365 RES A 444 3.21366 15.23418 17.54978 H_ 1 0 0.05269 +HETATM 366 H366 RES A 444 4.09659 13.20452 16.85511 H___A 1 0 0.20964 +HETATM 367 C367 RES A 444 10.00891 1.19780 16.80998 C_3 4 0 0.03193 +HETATM 368 O368 RES A 444 10.58951 1.67540 18.01757 O_3 2 2 -0.39965 +HETATM 369 H369 RES A 444 8.95573 0.97837 16.97853 H_ 1 0 0.05269 +HETATM 370 H370 RES A 444 10.09279 1.95889 16.03422 H_ 1 0 0.05269 +HETATM 371 H371 RES A 444 10.51430 0.28729 16.48583 H_ 1 0 0.05269 +HETATM 372 H372 RES A 444 11.54632 1.78202 17.83462 H___A 1 0 0.20964 +HETATM 373 C373 RES A 444 1.31776 5.21190 2.64974 C_3 4 0 0.03193 +HETATM 374 O374 RES A 444 0.78156 4.20400 1.79964 O_3 2 2 -0.39965 +HETATM 375 H375 RES A 444 2.00060 5.84322 2.08036 H_ 1 0 0.05269 +HETATM 376 H376 RES A 444 0.50993 5.82499 3.05018 H_ 1 0 0.05269 +HETATM 377 H377 RES A 444 1.85905 4.74873 3.47448 H_ 1 0 0.05269 +HETATM 378 H378 RES A 444 0.20631 3.65922 2.38482 H___A 1 0 0.20964 +HETATM 379 C379 RES A 444 5.74906 1.64126 13.27894 C_3 4 0 0.03193 +HETATM 380 O380 RES A 444 5.74933 0.96366 14.53304 O_3 2 2 -0.39965 +HETATM 381 H381 RES A 444 5.05775 2.48272 13.31880 H_ 1 0 0.05269 +HETATM 382 H382 RES A 444 6.74849 2.01315 13.05234 H_ 1 0 0.05269 +HETATM 383 H383 RES A 444 5.43187 0.95557 12.49248 H_ 1 0 0.05269 +HETATM 384 H384 RES A 444 6.42516 0.25912 14.43537 H___A 1 0 0.20964 +FORMAT CONECT (a6,12i6) +CONECT 1 2 3 4 5 +CONECT 2 1 6 +CONECT 3 1 +CONECT 4 1 +CONECT 5 1 +CONECT 6 2 +CONECT 7 8 9 10 11 +CONECT 8 7 12 +CONECT 9 7 +CONECT 10 7 +CONECT 11 7 +CONECT 12 8 +CONECT 13 14 15 16 17 +CONECT 14 13 18 +CONECT 15 13 +CONECT 16 13 +CONECT 17 13 +CONECT 18 14 +CONECT 19 20 21 22 23 +CONECT 20 19 24 +CONECT 21 19 +CONECT 22 19 +CONECT 23 19 +CONECT 24 20 +CONECT 25 26 27 28 29 +CONECT 26 25 30 +CONECT 27 25 +CONECT 28 25 +CONECT 29 25 +CONECT 30 26 +CONECT 31 32 33 34 35 +CONECT 32 31 36 +CONECT 33 31 +CONECT 34 31 +CONECT 35 31 +CONECT 36 32 +CONECT 37 38 39 40 41 +CONECT 38 37 42 +CONECT 39 37 +CONECT 40 37 +CONECT 41 37 +CONECT 42 38 +CONECT 43 44 45 46 47 +CONECT 44 43 48 +CONECT 45 43 +CONECT 46 43 +CONECT 47 43 +CONECT 48 44 +CONECT 49 50 51 52 53 +CONECT 50 49 54 +CONECT 51 49 +CONECT 52 49 +CONECT 53 49 +CONECT 54 50 +CONECT 55 56 57 58 59 +CONECT 56 55 60 +CONECT 57 55 +CONECT 58 55 +CONECT 59 55 +CONECT 60 56 +CONECT 61 62 63 64 65 +CONECT 62 61 66 +CONECT 63 61 +CONECT 64 61 +CONECT 65 61 +CONECT 66 62 +CONECT 67 68 69 70 71 +CONECT 68 67 72 +CONECT 69 67 +CONECT 70 67 +CONECT 71 67 +CONECT 72 68 +CONECT 73 74 75 76 77 +CONECT 74 73 78 +CONECT 75 73 +CONECT 76 73 +CONECT 77 73 +CONECT 78 74 +CONECT 79 80 81 82 83 +CONECT 80 79 84 +CONECT 81 79 +CONECT 82 79 +CONECT 83 79 +CONECT 84 80 +CONECT 85 86 87 88 89 +CONECT 86 85 90 +CONECT 87 85 +CONECT 88 85 +CONECT 89 85 +CONECT 90 86 +CONECT 91 92 93 94 95 +CONECT 92 91 96 +CONECT 93 91 +CONECT 94 91 +CONECT 95 91 +CONECT 96 92 +CONECT 97 98 99 100 101 +CONECT 98 97 102 +CONECT 99 97 +CONECT 100 97 +CONECT 101 97 +CONECT 102 98 +CONECT 103 104 105 106 107 +CONECT 104 103 108 +CONECT 105 103 +CONECT 106 103 +CONECT 107 103 +CONECT 108 104 +CONECT 109 110 111 112 113 +CONECT 110 109 114 +CONECT 111 109 +CONECT 112 109 +CONECT 113 109 +CONECT 114 110 +CONECT 115 116 117 118 119 +CONECT 116 115 120 +CONECT 117 115 +CONECT 118 115 +CONECT 119 115 +CONECT 120 116 +CONECT 121 122 123 124 125 +CONECT 122 121 126 +CONECT 123 121 +CONECT 124 121 +CONECT 125 121 +CONECT 126 122 +CONECT 127 128 129 130 131 +CONECT 128 127 132 +CONECT 129 127 +CONECT 130 127 +CONECT 131 127 +CONECT 132 128 +CONECT 133 134 135 136 137 +CONECT 134 133 138 +CONECT 135 133 +CONECT 136 133 +CONECT 137 133 +CONECT 138 134 +CONECT 139 140 141 142 143 +CONECT 140 139 144 +CONECT 141 139 +CONECT 142 139 +CONECT 143 139 +CONECT 144 140 +CONECT 145 146 147 148 149 +CONECT 146 145 150 +CONECT 147 145 +CONECT 148 145 +CONECT 149 145 +CONECT 150 146 +CONECT 151 152 153 154 155 +CONECT 152 151 156 +CONECT 153 151 +CONECT 154 151 +CONECT 155 151 +CONECT 156 152 +CONECT 157 158 159 160 161 +CONECT 158 157 162 +CONECT 159 157 +CONECT 160 157 +CONECT 161 157 +CONECT 162 158 +CONECT 163 164 165 166 167 +CONECT 164 163 168 +CONECT 165 163 +CONECT 166 163 +CONECT 167 163 +CONECT 168 164 +CONECT 169 170 171 172 173 +CONECT 170 169 174 +CONECT 171 169 +CONECT 172 169 +CONECT 173 169 +CONECT 174 170 +CONECT 175 176 177 178 179 +CONECT 176 175 180 +CONECT 177 175 +CONECT 178 175 +CONECT 179 175 +CONECT 180 176 +CONECT 181 182 183 184 185 +CONECT 182 181 186 +CONECT 183 181 +CONECT 184 181 +CONECT 185 181 +CONECT 186 182 +CONECT 187 188 189 190 191 +CONECT 188 187 192 +CONECT 189 187 +CONECT 190 187 +CONECT 191 187 +CONECT 192 188 +CONECT 193 194 195 196 197 +CONECT 194 193 198 +CONECT 195 193 +CONECT 196 193 +CONECT 197 193 +CONECT 198 194 +CONECT 199 200 201 202 203 +CONECT 200 199 204 +CONECT 201 199 +CONECT 202 199 +CONECT 203 199 +CONECT 204 200 +CONECT 205 206 207 208 209 +CONECT 206 205 210 +CONECT 207 205 +CONECT 208 205 +CONECT 209 205 +CONECT 210 206 +CONECT 211 212 213 214 215 +CONECT 212 211 216 +CONECT 213 211 +CONECT 214 211 +CONECT 215 211 +CONECT 216 212 +CONECT 217 218 219 220 221 +CONECT 218 217 222 +CONECT 219 217 +CONECT 220 217 +CONECT 221 217 +CONECT 222 218 +CONECT 223 224 225 226 227 +CONECT 224 223 228 +CONECT 225 223 +CONECT 226 223 +CONECT 227 223 +CONECT 228 224 +CONECT 229 230 231 232 233 +CONECT 230 229 234 +CONECT 231 229 +CONECT 232 229 +CONECT 233 229 +CONECT 234 230 +CONECT 235 236 237 238 239 +CONECT 236 235 240 +CONECT 237 235 +CONECT 238 235 +CONECT 239 235 +CONECT 240 236 +CONECT 241 242 243 244 245 +CONECT 242 241 246 +CONECT 243 241 +CONECT 244 241 +CONECT 245 241 +CONECT 246 242 +CONECT 247 248 249 250 251 +CONECT 248 247 252 +CONECT 249 247 +CONECT 250 247 +CONECT 251 247 +CONECT 252 248 +CONECT 253 254 255 256 257 +CONECT 254 253 258 +CONECT 255 253 +CONECT 256 253 +CONECT 257 253 +CONECT 258 254 +CONECT 259 260 261 262 263 +CONECT 260 259 264 +CONECT 261 259 +CONECT 262 259 +CONECT 263 259 +CONECT 264 260 +CONECT 265 266 267 268 269 +CONECT 266 265 270 +CONECT 267 265 +CONECT 268 265 +CONECT 269 265 +CONECT 270 266 +CONECT 271 272 273 274 275 +CONECT 272 271 276 +CONECT 273 271 +CONECT 274 271 +CONECT 275 271 +CONECT 276 272 +CONECT 277 278 279 280 281 +CONECT 278 277 282 +CONECT 279 277 +CONECT 280 277 +CONECT 281 277 +CONECT 282 278 +CONECT 283 284 285 286 287 +CONECT 284 283 288 +CONECT 285 283 +CONECT 286 283 +CONECT 287 283 +CONECT 288 284 +CONECT 289 290 291 292 293 +CONECT 290 289 294 +CONECT 291 289 +CONECT 292 289 +CONECT 293 289 +CONECT 294 290 +CONECT 295 296 297 298 299 +CONECT 296 295 300 +CONECT 297 295 +CONECT 298 295 +CONECT 299 295 +CONECT 300 296 +CONECT 301 302 303 304 305 +CONECT 302 301 306 +CONECT 303 301 +CONECT 304 301 +CONECT 305 301 +CONECT 306 302 +CONECT 307 308 309 310 311 +CONECT 308 307 312 +CONECT 309 307 +CONECT 310 307 +CONECT 311 307 +CONECT 312 308 +CONECT 313 314 315 316 317 +CONECT 314 313 318 +CONECT 315 313 +CONECT 316 313 +CONECT 317 313 +CONECT 318 314 +CONECT 319 320 321 322 323 +CONECT 320 319 324 +CONECT 321 319 +CONECT 322 319 +CONECT 323 319 +CONECT 324 320 +CONECT 325 326 327 328 329 +CONECT 326 325 330 +CONECT 327 325 +CONECT 328 325 +CONECT 329 325 +CONECT 330 326 +CONECT 331 332 333 334 335 +CONECT 332 331 336 +CONECT 333 331 +CONECT 334 331 +CONECT 335 331 +CONECT 336 332 +CONECT 337 338 339 340 341 +CONECT 338 337 342 +CONECT 339 337 +CONECT 340 337 +CONECT 341 337 +CONECT 342 338 +CONECT 343 344 345 346 347 +CONECT 344 343 348 +CONECT 345 343 +CONECT 346 343 +CONECT 347 343 +CONECT 348 344 +CONECT 349 350 351 352 353 +CONECT 350 349 354 +CONECT 351 349 +CONECT 352 349 +CONECT 353 349 +CONECT 354 350 +CONECT 355 356 357 358 359 +CONECT 356 355 360 +CONECT 357 355 +CONECT 358 355 +CONECT 359 355 +CONECT 360 356 +CONECT 361 362 363 364 365 +CONECT 362 361 366 +CONECT 363 361 +CONECT 364 361 +CONECT 365 361 +CONECT 366 362 +CONECT 367 368 369 370 371 +CONECT 368 367 372 +CONECT 369 367 +CONECT 370 367 +CONECT 371 367 +CONECT 372 368 +CONECT 373 374 375 376 377 +CONECT 374 373 378 +CONECT 375 373 +CONECT 376 373 +CONECT 377 373 +CONECT 378 374 +CONECT 379 380 381 382 383 +CONECT 380 379 384 +CONECT 381 379 +CONECT 382 379 +CONECT 383 379 +CONECT 384 380 +END diff --git a/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat b/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat new file mode 100644 index 0000000000..b856598735 --- /dev/null +++ b/examples/dreiding/ch3oh.box.dreiding.cerius2.eng.dat @@ -0,0 +1,56 @@ +Energy expression created for 3D-periodic boundary conditions. + Cell information: + Density (g/cc): 0.4573 + Volume (A**3): 7447.2363 + A: 19.9969 Alpha: 90.0000 + B: 19.1282 Beta : 90.0000 + C: 19.4697 Gamma: 90.0000 + + Summary of the energy expression: + Movable atoms : 384 Fixed atoms : 0 + Polar atoms : 0 + Bonds : 320 Angles : 448 + Torsions : 192 Inversions : 0 + Urey-Bradley : 0 Bend-bend : 0 + Stretch-stretch : 0 Sep-stretch-stretch : 0 + Stretch-bend-stretch : 0 Torsion-stretch : 0 + Torsion-bend-bend : 0 Stretch-torsion-stretch: 0 + Bend-torsion-bend : 0 + Hydrogen-bond acceptors: 64 Hydrogen-bond donors : 64 + Nonbond exclusions : 768 Polar-polar exclusions : 0 + + Total charge : -0.001 Movable atoms only : -0.001 + Total mass : 2050.688 Movable atoms only : 2050.688 + +Automatically calculating Ewald parameters for Coulomb sum. + +Summary of Non-bond set up :- + Non-bond list cutoff radius : 13.530 (A) + Number of non-bond terms in list : 101788 + This has been updated 1 times since the energy expression was created. + + Using Ewald sums for Coulomb terms with: + Eta=3.932, Rcut=11.530, Kcut=0.298, Acc.=0.001 + +VDW terms truncated at : 8.500 (A) + +Diagonal VdW parameters combined using the arithmetic combination rule. + +Summary of H-bond set up using a h-bond list. + +There are 604 interactions within hbond cutoffs of + Donor-acceptor distances less than 6.500 (A) and + Donor-h-acceptor angles greater than 90.000 (degrees) + +************************************************************************ + Energy Decomposition + Valence Terms Nonbond Terms + Bonds : 0.535675 Van der Waals : -56.0592 + Angles : 1.28188 Electrostatic : 234.036 + Torsions : 1.23250 Hydrogen Bonds: -68.7337 + Inversions : 0.000000E+00 Restraints : 0.000000E+00 + Urey-Bradley : 0.000000E+00 3-Body : 0.000000E+00 + Cross-Terms : 0.000000E+00 + Total Energy : 112.293 +************************************************************************ + diff --git a/examples/dreiding/data.dreiding b/examples/dreiding/data.dreiding new file mode 100644 index 0000000000..f6d9bcf22d --- /dev/null +++ b/examples/dreiding/data.dreiding @@ -0,0 +1,1400 @@ +Created on Mon Oct 3 10:06:14 2011 + + 384 atoms + 320 bonds + 448 angles + 192 dihedrals + 0 impropers + + 4 atom types + 3 bond types + 2 angle types + 1 dihedral types + 0 improper types + + 0.000000 19.996890 xlo xhi + 0.000000 19.128160 ylo yhi + 0.000000 19.469710 zlo zhi + +Masses + + 1 1.0080 # H_ + 2 1.0080 # H___A + 3 12.0110 # C_3 + 4 15.9994 # O_3 + + +Bond Coeffs + + 1 350 1.42 # O_3 C_3 + 2 350 0.98 # O_3 H___A + 3 350 1.09 # C_3 H_ + +Angle Coeffs + + 1 50 104.51 # X O_3 X + 2 50 109.471 # X C_3 X + +Dihedral Coeffs + + 1 0.333333 1 3 # X O_3 C_3 X + +Atoms + + 1 444 3 0.03193 9.75768 9.43603 9.44978 0 0 0 + 2 444 4 -0.39965 9.07001 9.89252 10.61030 0 0 0 + 3 444 1 0.05269 9.56169 8.37372 9.30573 0 0 0 + 4 444 1 0.05269 9.40633 9.98872 8.57739 0 0 0 + 5 444 1 0.05269 10.83081 9.58873 9.56849 0 0 0 + 6 444 2 0.20964 9.28861 10.84826 10.67569 0 0 0 + 7 444 3 0.03193 7.87790 6.57305 4.37926 0 0 0 + 8 444 4 -0.39965 9.21046 6.55811 3.88167 0 0 0 + 9 444 1 0.05269 7.42565 7.54437 4.17519 0 0 0 + 10 444 1 0.05269 7.28908 5.79550 3.89029 0 0 0 + 11 444 1 0.05269 7.88159 6.39628 5.45605 0 0 0 + 12 444 2 0.20964 9.55621 5.66386 4.09964 0 0 0 + 13 444 3 0.03193 19.38728 8.01844 0.29841 0 0 0 + 14 444 4 -0.39965 18.30059 8.67235 0.94403 0 0 0 + 15 444 1 0.05269 20.09420 7.66052 1.04704 0 0 0 + 16 444 1 0.05269 19.01558 7.17130 -0.27928 0 0 0 + 17 444 1 0.05269 19.89453 8.71684 -0.36839 0 0 0 + 18 444 2 0.20964 17.72537 8.98355 0.21436 0 0 0 + 19 444 3 0.03193 3.43963 14.29741 12.62221 0 0 0 + 20 444 4 -0.39965 3.07671 15.61822 12.23631 0 0 0 + 21 444 1 0.05269 4.27302 14.34187 13.32349 0 0 0 + 22 444 1 0.05269 2.59308 13.81008 13.10508 0 0 0 + 23 444 1 0.05269 3.73991 13.72415 11.74356 0 0 0 + 24 444 2 0.20964 2.32966 15.52033 11.61130 0 0 0 + 25 444 3 0.03193 16.06751 17.84957 14.39706 0 0 0 + 26 444 4 -0.39965 15.98970 19.07282 15.11734 0 0 0 + 27 444 1 0.05269 16.77526 17.18402 14.89204 0 0 0 + 28 444 1 0.05269 15.08510 17.37867 14.36938 0 0 0 + 29 444 1 0.05269 16.40684 18.04085 13.37809 0 0 0 + 30 444 2 0.20964 15.35997 19.62900 14.61094 0 0 0 + 31 444 3 0.03193 5.61540 13.90261 0.28024 0 0 0 + 32 444 4 -0.39965 6.96329 14.33980 0.39819 0 0 0 + 33 444 1 0.05269 5.39381 13.18200 1.06831 0 0 0 + 34 444 1 0.05269 4.93854 14.75467 0.36989 0 0 0 + 35 444 1 0.05269 5.46825 13.42632 -0.68848 0 0 0 + 36 444 2 0.20964 7.08381 14.99923 -0.31851 0 0 0 + 37 444 3 0.03193 10.38444 13.74977 1.74423 0 0 0 + 38 444 4 -0.39965 10.34865 13.00890 2.96031 0 0 0 + 39 444 1 0.05269 11.31498 14.30998 1.68756 0 0 0 + 40 444 1 0.05269 10.32135 13.06875 0.89580 0 0 0 + 41 444 1 0.05269 9.54190 14.44190 1.71309 0 0 0 + 42 444 2 0.20964 9.45315 12.60486 2.98815 0 0 0 + 43 444 3 0.03193 2.71877 -0.19852 13.91482 0 0 0 + 44 444 4 -0.39965 2.55981 1.00656 13.16980 0 0 0 + 45 444 1 0.05269 3.42887 -0.85053 13.40421 0 0 0 + 46 444 1 0.05269 3.09835 0.02977 14.91227 0 0 0 + 47 444 1 0.05269 1.76062 -0.71177 13.99933 0 0 0 + 48 444 2 0.20964 1.92580 1.55260 13.68058 0 0 0 + 49 444 3 0.03193 12.86271 12.87291 9.10254 0 0 0 + 50 444 4 -0.39965 12.72964 12.19590 7.85730 0 0 0 + 51 444 1 0.05269 11.91715 12.83126 9.64447 0 0 0 + 52 444 1 0.05269 13.63913 12.39659 9.70188 0 0 0 + 53 444 1 0.05269 13.12955 13.91577 8.92585 0 0 0 + 54 444 2 0.20964 13.60640 12.28637 7.42000 0 0 0 + 55 444 3 0.03193 0.91345 1.84436 7.21758 0 0 0 + 56 444 4 -0.39965 0.16704 0.83109 7.88260 0 0 0 + 57 444 1 0.05269 1.73149 1.39473 6.65448 0 0 0 + 58 444 1 0.05269 0.25949 2.38287 6.53090 0 0 0 + 59 444 1 0.05269 1.31674 2.54212 7.95173 0 0 0 + 60 444 2 0.20964 0.79209 0.41480 8.51642 0 0 0 + 61 444 3 0.03193 3.28235 16.40235 6.34784 0 0 0 + 62 444 4 -0.39965 4.40446 15.86811 5.64397 0 0 0 + 63 444 1 0.05269 3.52775 16.47384 7.40940 0 0 0 + 64 444 1 0.05269 3.04852 17.39543 5.96551 0 0 0 + 65 444 1 0.05269 2.41989 15.75077 6.22278 0 0 0 + 66 444 2 0.20964 4.15040 15.88018 4.69552 0 0 0 + 67 444 3 0.03193 14.28685 11.84833 2.69644 0 0 0 + 68 444 4 -0.39965 14.47540 12.00775 4.09802 0 0 0 + 69 444 1 0.05269 15.22519 11.52503 2.24449 0 0 0 + 70 444 1 0.05269 13.51978 11.09713 2.50925 0 0 0 + 71 444 1 0.05269 13.98187 12.79680 2.25228 0 0 0 + 72 444 2 0.20964 13.60420 12.29868 4.44979 0 0 0 + 73 444 3 0.03193 3.74650 0.37490 9.28202 0 0 0 + 74 444 4 -0.39965 4.68624 1.26369 8.68537 0 0 0 + 75 444 1 0.05269 4.28178 -0.38700 9.84868 0 0 0 + 76 444 1 0.05269 3.08874 0.92642 9.95440 0 0 0 + 77 444 1 0.05269 3.15691 -0.10643 8.50276 0 0 0 + 78 444 2 0.20964 4.15269 1.92251 8.18619 0 0 0 + 79 444 3 0.03193 17.93191 1.98830 17.28592 0 0 0 + 80 444 4 -0.39965 16.68990 1.36769 17.60090 0 0 0 + 81 444 1 0.05269 18.23740 2.63433 18.10865 0 0 0 + 82 444 1 0.05269 18.69345 1.22519 17.12938 0 0 0 + 83 444 1 0.05269 17.82727 2.59026 16.38313 0 0 0 + 84 444 2 0.20964 16.45659 0.83462 16.81232 0 0 0 + 85 444 3 0.03193 4.61466 10.52979 17.10957 0 0 0 + 86 444 4 -0.39965 3.62035 11.42538 17.60198 0 0 0 + 87 444 1 0.05269 5.60177 10.98718 17.19552 0 0 0 + 88 444 1 0.05269 4.60514 9.60666 17.68872 0 0 0 + 89 444 1 0.05269 4.42040 10.30112 16.06086 0 0 0 + 90 444 2 0.20964 2.76200 10.96432 17.46823 0 0 0 + 91 444 3 0.03193 4.21479 2.76452 1.93621 0 0 0 + 92 444 4 -0.39965 3.45640 2.43822 3.09183 0 0 0 + 93 444 1 0.05269 5.15561 3.22498 2.23935 0 0 0 + 94 444 1 0.05269 4.42333 1.85922 1.36296 0 0 0 + 95 444 1 0.05269 3.65868 3.46500 1.31342 0 0 0 + 96 444 2 0.20964 2.68968 1.92747 2.75853 0 0 0 + 97 444 3 0.03193 2.10781 10.76856 1.36312 0 0 0 + 98 444 4 -0.39965 0.80698 11.27394 1.07892 0 0 0 + 99 444 1 0.05269 2.85114 11.53660 1.14272 0 0 0 + 100 444 1 0.05269 2.17873 10.49350 2.41651 0 0 0 + 101 444 1 0.05269 2.31220 9.89096 0.74802 0 0 0 + 102 444 2 0.20964 0.18009 10.55168 1.30975 0 0 0 + 103 444 3 0.03193 16.26093 8.92927 6.57643 0 0 0 + 104 444 4 -0.39965 15.77968 8.06983 7.60177 0 0 0 + 105 444 1 0.05269 17.30509 9.17300 6.76897 0 0 0 + 106 444 1 0.05269 16.18069 8.42876 5.61195 0 0 0 + 107 444 1 0.05269 15.67380 9.84869 6.55835 0 0 0 + 108 444 2 0.20964 14.84042 7.91008 7.37720 0 0 0 + 109 444 3 0.03193 17.80004 2.06792 1.87371 0 0 0 + 110 444 4 -0.39965 18.48862 0.99081 1.24012 0 0 0 + 111 444 1 0.05269 18.23871 2.25534 2.85453 0 0 0 + 112 444 1 0.05269 17.87937 2.96817 1.26859 0 0 0 + 113 444 1 0.05269 16.74643 1.80633 1.99693 0 0 0 + 114 444 2 0.20964 18.02202 0.85350 0.38356 0 0 0 + 115 444 3 0.03193 13.75521 14.57173 15.42181 0 0 0 + 116 444 4 -0.39965 12.73183 15.48504 15.80455 0 0 0 + 117 444 1 0.05269 14.51862 14.53760 16.20019 0 0 0 + 118 444 1 0.05269 13.33164 13.57618 15.29114 0 0 0 + 119 444 1 0.05269 14.21175 14.89091 14.48437 0 0 0 + 120 444 2 0.20964 12.11746 15.52768 15.03694 0 0 0 + 121 444 3 0.03193 6.22569 16.46321 11.49168 0 0 0 + 122 444 4 -0.39965 7.37834 15.65849 11.27192 0 0 0 + 123 444 1 0.05269 6.47325 17.50688 11.31115 0 0 0 + 124 444 1 0.05269 5.42639 16.16714 10.80967 0 0 0 + 125 444 1 0.05269 5.88670 16.35324 12.52283 0 0 0 + 126 444 2 0.20964 7.09224 14.73066 11.41776 0 0 0 + 127 444 3 0.03193 20.01012 9.33317 4.86657 0 0 0 + 128 444 4 -0.39965 19.63827 8.14994 5.56401 0 0 0 + 129 444 1 0.05269 20.82510 9.82112 5.40128 0 0 0 + 130 444 1 0.05269 20.34186 9.07963 3.85908 0 0 0 + 131 444 1 0.05269 19.16051 10.01349 4.80673 0 0 0 + 132 444 2 0.20964 18.86130 7.79949 5.07585 0 0 0 + 133 444 3 0.03193 5.99486 1.97634 5.72513 0 0 0 + 134 444 4 -0.39965 6.74021 3.13466 6.08586 0 0 0 + 135 444 1 0.05269 4.92875 2.19578 5.79288 0 0 0 + 136 444 1 0.05269 6.23376 1.68432 4.70221 0 0 0 + 137 444 1 0.05269 6.23815 1.15441 6.40034 0 0 0 + 138 444 2 0.20964 7.67684 2.83917 6.07790 0 0 0 + 139 444 3 0.03193 13.03835 7.12913 5.28770 0 0 0 + 140 444 4 -0.39965 13.02644 7.55487 6.64544 0 0 0 + 141 444 1 0.05269 12.06949 6.70203 5.02747 0 0 0 + 142 444 1 0.05269 13.24117 7.98172 4.63978 0 0 0 + 143 444 1 0.05269 13.81531 6.37647 5.14697 0 0 0 + 144 444 2 0.20964 12.38966 8.29858 6.65964 0 0 0 + 145 444 3 0.03193 10.64649 1.42163 6.99575 0 0 0 + 146 444 4 -0.39965 11.32932 1.55767 8.23581 0 0 0 + 147 444 1 0.05269 9.77461 0.78340 7.13967 0 0 0 + 148 444 1 0.05269 10.32031 2.40213 6.64261 0 0 0 + 149 444 1 0.05269 11.30461 0.96891 6.25436 0 0 0 + 150 444 2 0.20964 12.13048 2.09412 8.04749 0 0 0 + 151 444 3 0.03193 7.70974 10.56643 0.43745 0 0 0 + 152 444 4 -0.39965 6.69643 10.25499 1.38817 0 0 0 + 153 444 1 0.05269 8.59868 10.91732 0.96199 0 0 0 + 154 444 1 0.05269 7.96121 9.67471 -0.13665 0 0 0 + 155 444 1 0.05269 7.36428 11.34806 -0.24011 0 0 0 + 156 444 2 0.20964 5.94241 9.89154 0.87302 0 0 0 + 157 444 3 0.03193 12.78344 1.18067 14.16301 0 0 0 + 158 444 4 -0.39965 14.01647 1.62010 13.60417 0 0 0 + 159 444 1 0.05269 12.98217 0.47776 14.97222 0 0 0 + 160 444 1 0.05269 12.23227 2.03435 14.55662 0 0 0 + 161 444 1 0.05269 12.18352 0.68832 13.39874 0 0 0 + 162 444 2 0.20964 13.77530 2.26070 12.89474 0 0 0 + 163 444 3 0.03193 16.94139 17.42253 1.05686 0 0 0 + 164 444 4 -0.39965 16.08424 16.29569 1.04946 0 0 0 + 165 444 1 0.05269 17.18791 17.69368 0.02960 0 0 0 + 166 444 1 0.05269 16.43795 18.25970 1.54236 0 0 0 + 167 444 1 0.05269 17.85566 17.18021 1.60025 0 0 0 + 168 444 2 0.20964 15.85827 16.14412 1.99459 0 0 0 + 169 444 3 0.03193 12.48878 18.07306 2.58158 0 0 0 + 170 444 4 -0.39965 13.76343 18.70451 2.65479 0 0 0 + 171 444 1 0.05269 12.02971 18.30966 1.62310 0 0 0 + 172 444 1 0.05269 12.61189 16.99304 2.67149 0 0 0 + 173 444 1 0.05269 11.85062 18.43623 3.38623 0 0 0 + 174 444 2 0.20964 14.05960 18.54980 3.57438 0 0 0 + 175 444 3 0.03193 19.92937 14.32320 3.09954 0 0 0 + 176 444 4 -0.39965 20.47921 14.98239 4.23349 0 0 0 + 177 444 1 0.05269 19.06424 14.88021 2.74247 0 0 0 + 178 444 1 0.05269 20.67424 14.26863 2.30532 0 0 0 + 179 444 1 0.05269 19.62003 13.31457 3.37662 0 0 0 + 180 444 2 0.20964 21.24382 14.42340 4.50083 0 0 0 + 181 444 3 0.03193 10.63009 10.62036 5.48247 0 0 0 + 182 444 4 -0.39965 11.32080 9.96459 6.53930 0 0 0 + 183 444 1 0.05269 9.97896 9.90801 4.97371 0 0 0 + 184 444 1 0.05269 10.02580 11.43533 5.88411 0 0 0 + 185 444 1 0.05269 11.34799 11.02578 4.76860 0 0 0 + 186 444 2 0.20964 11.85790 10.67095 6.95281 0 0 0 + 187 444 3 0.03193 15.65699 9.09727 17.99408 0 0 0 + 188 444 4 -0.39965 16.90142 9.78939 17.98916 0 0 0 + 189 444 1 0.05269 15.04412 9.44428 18.82685 0 0 0 + 190 444 1 0.05269 15.12611 9.28242 17.05809 0 0 0 + 191 444 1 0.05269 15.82887 8.02576 18.10423 0 0 0 + 192 444 2 0.20964 17.40700 9.38003 17.24481 0 0 0 + 193 444 3 0.03193 17.18063 5.09511 5.97377 0 0 0 + 194 444 4 -0.39965 17.00699 3.69621 6.16625 0 0 0 + 195 444 1 0.05269 16.80087 5.38050 4.99222 0 0 0 + 196 444 1 0.05269 16.63290 5.63866 6.74297 0 0 0 + 197 444 1 0.05269 18.23947 5.34654 6.03632 0 0 0 + 198 444 2 0.20964 17.37922 3.51369 7.05728 0 0 0 + 199 444 3 0.03193 9.27176 16.96360 18.60348 0 0 0 + 200 444 4 -0.39965 10.16048 17.88001 19.23027 0 0 0 + 201 444 1 0.05269 8.24372 17.25233 18.82182 0 0 0 + 202 444 1 0.05269 9.42846 16.97594 17.52377 0 0 0 + 203 444 1 0.05269 9.45162 15.95835 18.98512 0 0 0 + 204 444 2 0.20964 11.05433 17.57777 18.98374 0 0 0 + 205 444 3 0.03193 19.02698 11.32629 8.74382 0 0 0 + 206 444 4 -0.39965 19.55395 11.57496 7.44476 0 0 0 + 207 444 1 0.05269 19.84306 11.28874 9.46486 0 0 0 + 208 444 1 0.05269 18.34041 12.12651 9.02172 0 0 0 + 209 444 1 0.05269 18.49941 10.37268 8.75573 0 0 0 + 210 444 2 0.20964 18.77484 11.55877 6.84653 0 0 0 + 211 444 3 0.03193 13.70984 17.91381 18.18096 0 0 0 + 212 444 4 -0.39965 12.78082 16.86629 18.42949 0 0 0 + 213 444 1 0.05269 14.65264 17.49419 17.82801 0 0 0 + 214 444 1 0.05269 13.30579 18.58561 17.42320 0 0 0 + 215 444 1 0.05269 13.88737 18.47185 19.10049 0 0 0 + 216 444 2 0.20964 12.70938 16.39241 17.57615 0 0 0 + 217 444 3 0.03193 7.96084 1.88854 9.90132 0 0 0 + 218 444 4 -0.39965 7.16836 0.76877 10.27166 0 0 0 + 219 444 1 0.05269 8.08701 1.90679 8.82000 0 0 0 + 220 444 1 0.05269 7.47244 2.80930 10.22050 0 0 0 + 221 444 1 0.05269 8.93667 1.81039 10.37952 0 0 0 + 222 444 2 0.20964 6.33219 0.87991 9.77220 0 0 0 + 223 444 3 0.03193 8.67989 16.70958 5.83790 0 0 0 + 224 444 4 -0.39965 8.12024 17.60224 6.79460 0 0 0 + 225 444 1 0.05269 8.09228 16.75013 4.91967 0 0 0 + 226 444 1 0.05269 9.70728 17.00048 5.62151 0 0 0 + 227 444 1 0.05269 8.66415 15.69153 6.22812 0 0 0 + 228 444 2 0.20964 8.61953 17.44038 7.62546 0 0 0 + 229 444 3 0.03193 8.92912 4.00904 0.50900 0 0 0 + 230 444 4 -0.39965 8.96759 5.27857 -0.13058 0 0 0 + 231 444 1 0.05269 8.33969 4.08141 1.42278 0 0 0 + 232 444 1 0.05269 8.47682 3.27429 -0.15833 0 0 0 + 233 444 1 0.05269 9.94193 3.69036 0.75961 0 0 0 + 234 444 2 0.20964 9.53405 5.14064 -0.92363 0 0 0 + 235 444 3 0.03193 14.12006 6.78048 11.59632 0 0 0 + 236 444 4 -0.39965 13.07688 7.13628 10.69542 0 0 0 + 237 444 1 0.05269 14.86068 7.57932 11.63302 0 0 0 + 238 444 1 0.05269 13.70582 6.62813 12.59405 0 0 0 + 239 444 1 0.05269 14.60290 5.86276 11.26001 0 0 0 + 240 444 2 0.20964 12.46641 6.36815 10.68540 0 0 0 + 241 444 3 0.03193 11.17366 12.60541 17.35410 0 0 0 + 242 444 4 -0.39965 11.02139 13.96786 17.73395 0 0 0 + 243 444 1 0.05269 10.47704 11.99021 17.92352 0 0 0 + 244 444 1 0.05269 10.96097 12.49402 16.29011 0 0 0 + 245 444 1 0.05269 12.19388 12.27752 17.55780 0 0 0 + 246 444 2 0.20964 11.62997 14.46572 17.15437 0 0 0 + 247 444 3 0.03193 13.59375 17.68257 6.60725 0 0 0 + 248 444 4 -0.39965 14.41796 18.19915 5.56896 0 0 0 + 249 444 1 0.05269 12.56750 17.59958 6.25257 0 0 0 + 250 444 1 0.05269 13.95140 16.69610 6.90350 0 0 0 + 251 444 1 0.05269 13.62441 18.35441 7.46523 0 0 0 + 252 444 2 0.20964 15.31701 18.26489 5.96089 0 0 0 + 253 444 3 0.03193 5.00550 8.70879 7.93082 0 0 0 + 254 444 4 -0.39965 5.30633 7.53730 7.17920 0 0 0 + 255 444 1 0.05269 3.92410 8.80228 8.03546 0 0 0 + 256 444 1 0.05269 5.45973 8.64206 8.92134 0 0 0 + 257 444 1 0.05269 5.39337 9.58812 7.41497 0 0 0 + 258 444 2 0.20964 6.28240 7.52607 7.08649 0 0 0 + 259 444 3 0.03193 19.22046 1.28969 13.91270 0 0 0 + 260 444 4 -0.39965 20.08805 2.12898 14.66921 0 0 0 + 261 444 1 0.05269 18.36269 1.87059 13.57299 0 0 0 + 262 444 1 0.05269 19.74873 0.89208 13.04541 0 0 0 + 263 444 1 0.05269 18.87095 0.46148 14.53042 0 0 0 + 264 444 2 0.20964 20.73583 1.52580 15.09558 0 0 0 + 265 444 3 0.03193 5.65052 5.42047 10.40141 0 0 0 + 266 444 4 -0.39965 6.43233 5.15576 11.55959 0 0 0 + 267 444 1 0.05269 4.77591 4.76790 10.40245 0 0 0 + 268 444 1 0.05269 5.31750 6.45945 10.40208 0 0 0 + 269 444 1 0.05269 6.23775 5.22771 9.50311 0 0 0 + 270 444 2 0.20964 7.22334 5.73649 11.49818 0 0 0 + 271 444 3 0.03193 13.28289 5.81639 20.26495 0 0 0 + 272 444 4 -0.39965 14.46108 5.91020 19.47306 0 0 0 + 273 444 1 0.05269 12.54449 6.53149 19.89956 0 0 0 + 274 444 1 0.05269 12.86565 4.81041 20.20085 0 0 0 + 275 444 1 0.05269 13.51599 6.04282 21.30628 0 0 0 + 276 444 2 0.20964 15.06689 5.21681 19.82048 0 0 0 + 277 444 3 0.03193 8.93119 18.18764 13.28407 0 0 0 + 278 444 4 -0.39965 7.83369 17.94987 14.15258 0 0 0 + 279 444 1 0.05269 8.62256 18.85058 12.47662 0 0 0 + 280 444 1 0.05269 9.74951 18.65521 13.83984 0 0 0 + 281 444 1 0.05269 9.27914 17.24313 12.85839 0 0 0 + 282 444 2 0.20964 8.18034 17.33710 14.83873 0 0 0 + 283 444 3 0.03193 5.79456 2.19968 17.80701 0 0 0 + 284 444 4 -0.39965 6.24133 2.96696 16.69489 0 0 0 + 285 444 1 0.05269 5.95925 2.76662 18.72146 0 0 0 + 286 444 1 0.05269 4.73133 1.97951 17.70368 0 0 0 + 287 444 1 0.05269 6.35360 1.26369 17.85787 0 0 0 + 288 444 2 0.20964 6.11167 2.36984 15.93032 0 0 0 + 289 444 3 0.03193 7.02257 8.31146 13.32419 0 0 0 + 290 444 4 -0.39965 6.81830 9.58617 13.92250 0 0 0 + 291 444 1 0.05269 6.70351 7.53159 14.01772 0 0 0 + 292 444 1 0.05269 6.43819 8.23664 12.40602 0 0 0 + 293 444 1 0.05269 8.08019 8.17829 13.09255 0 0 0 + 294 444 2 0.20964 7.15181 10.23194 13.26245 0 0 0 + 295 444 3 0.03193 14.02631 3.46938 16.96774 0 0 0 + 296 444 4 -0.39965 13.54366 2.24600 17.51611 0 0 0 + 297 444 1 0.05269 13.77498 3.53066 15.91013 0 0 0 + 298 444 1 0.05269 13.56595 4.30739 17.48900 0 0 0 + 299 444 1 0.05269 15.10861 3.52592 17.07904 0 0 0 + 300 444 2 0.20964 13.94305 2.20406 18.41525 0 0 0 + 301 444 3 0.03193 1.20831 18.57486 2.95108 0 0 0 + 302 444 4 -0.39965 1.22576 19.81993 2.26075 0 0 0 + 303 444 1 0.05269 0.55458 18.64320 3.82147 0 0 0 + 304 444 1 0.05269 0.84728 17.78646 2.28798 0 0 0 + 305 444 1 0.05269 2.21813 18.32995 3.28130 0 0 0 + 306 444 2 0.20964 0.30364 19.97372 1.97883 0 0 0 + 307 444 3 0.03193 13.27354 18.56828 10.67719 0 0 0 + 308 444 4 -0.39965 12.48821 17.54334 10.07841 0 0 0 + 309 444 1 0.05269 12.67535 19.47728 10.75867 0 0 0 + 310 444 1 0.05269 13.59103 18.25289 11.67155 0 0 0 + 311 444 1 0.05269 14.15208 18.77184 10.06448 0 0 0 + 312 444 2 0.20964 13.09935 16.78781 9.93641 0 0 0 + 313 444 3 0.03193 6.36730 14.29234 8.10345 0 0 0 + 314 444 4 -0.39965 6.40678 13.98673 6.71535 0 0 0 + 315 444 1 0.05269 5.36805 14.09806 8.49177 0 0 0 + 316 444 1 0.05269 7.08832 13.66856 8.63166 0 0 0 + 317 444 1 0.05269 6.61905 15.34196 8.25886 0 0 0 + 318 444 2 0.20964 5.76587 14.60457 6.30951 0 0 0 + 319 444 3 0.03193 2.65328 9.08063 11.58358 0 0 0 + 320 444 4 -0.39965 2.00217 9.04988 10.31818 0 0 0 + 321 444 1 0.05269 2.77179 8.06201 11.95511 0 0 0 + 322 444 1 0.05269 3.63556 9.54427 11.48302 0 0 0 + 323 444 1 0.05269 2.05382 9.65342 12.29226 0 0 0 + 324 444 2 0.20964 1.90245 9.98881 10.05330 0 0 0 + 325 444 3 0.03193 16.09537 13.47946 18.75299 0 0 0 + 326 444 4 -0.39965 15.35647 12.29789 19.02596 0 0 0 + 327 444 1 0.05269 15.44738 14.34606 18.88103 0 0 0 + 328 444 1 0.05269 16.93959 13.54850 19.44072 0 0 0 + 329 444 1 0.05269 16.46394 13.45617 17.72675 0 0 0 + 330 444 2 0.20964 15.94172 11.56097 18.74998 0 0 0 + 331 444 3 0.03193 5.36713 6.40841 19.02468 0 0 0 + 332 444 4 -0.39965 6.23337 6.92207 18.01801 0 0 0 + 333 444 1 0.05269 4.33549 6.65297 18.77623 0 0 0 + 334 444 1 0.05269 5.47707 5.32425 19.08654 0 0 0 + 335 444 1 0.05269 5.62819 6.85675 19.98559 0 0 0 + 336 444 2 0.20964 7.13950 6.67949 18.31120 0 0 0 + 337 444 3 0.03193 1.77513 13.81811 9.21198 0 0 0 + 338 444 4 -0.39965 0.83100 14.28966 10.16552 0 0 0 + 339 444 1 0.05269 1.29728 13.75593 8.23483 0 0 0 + 340 444 1 0.05269 2.62178 14.50388 9.15673 0 0 0 + 341 444 1 0.05269 2.12880 12.82836 9.50371 0 0 0 + 342 444 2 0.20964 1.30194 14.30478 11.02173 0 0 0 + 343 444 3 0.03193 21.59943 4.06368 17.75073 0 0 0 + 344 444 4 -0.39965 21.85233 3.04768 18.71336 0 0 0 + 345 444 1 0.05269 22.11092 3.81498 16.82008 0 0 0 + 346 444 1 0.05269 20.52800 4.13659 17.56408 0 0 0 + 347 444 1 0.05269 21.97071 5.01986 18.11886 0 0 0 + 348 444 2 0.20964 21.40074 3.34325 19.53474 0 0 0 + 349 444 3 0.03193 16.52622 4.73908 13.63762 0 0 0 + 350 444 4 -0.39965 15.55282 5.45454 14.38889 0 0 0 + 351 444 1 0.05269 16.03370 3.96708 13.04616 0 0 0 + 352 444 1 0.05269 17.05262 5.42291 12.96909 0 0 0 + 353 444 1 0.05269 17.24076 4.27126 14.31456 0 0 0 + 354 444 2 0.20964 16.06701 6.07053 14.95693 0 0 0 + 355 444 3 0.03193 20.20141 14.20302 18.50889 0 0 0 + 356 444 4 -0.39965 21.44729 13.78288 19.04009 0 0 0 + 357 444 1 0.05269 20.32931 15.13613 17.95996 0 0 0 + 358 444 1 0.05269 19.81275 13.43791 17.83324 0 0 0 + 359 444 1 0.05269 19.48848 14.36395 19.32079 0 0 0 + 360 444 2 0.20964 21.25026 12.96615 19.54627 0 0 0 + 361 444 3 0.03193 3.32298 14.94425 16.50422 0 0 0 + 362 444 4 -0.39965 4.38694 14.00670 16.37303 0 0 0 + 363 444 1 0.05269 3.54498 15.83135 15.91086 0 0 0 + 364 444 1 0.05269 2.39143 14.50263 16.15017 0 0 0 + 365 444 1 0.05269 3.21366 15.23418 17.54978 0 0 0 + 366 444 2 0.20964 4.09659 13.20452 16.85511 0 0 0 + 367 444 3 0.03193 10.00891 1.19780 16.80998 0 0 0 + 368 444 4 -0.39965 10.58951 1.67540 18.01757 0 0 0 + 369 444 1 0.05269 8.95573 0.97837 16.97853 0 0 0 + 370 444 1 0.05269 10.09279 1.95889 16.03422 0 0 0 + 371 444 1 0.05269 10.51430 0.28729 16.48583 0 0 0 + 372 444 2 0.20964 11.54632 1.78202 17.83462 0 0 0 + 373 444 3 0.03193 1.31776 5.21190 2.64974 0 0 0 + 374 444 4 -0.39965 0.78156 4.20400 1.79964 0 0 0 + 375 444 1 0.05269 2.00060 5.84322 2.08036 0 0 0 + 376 444 1 0.05269 0.50993 5.82499 3.05018 0 0 0 + 377 444 1 0.05269 1.85905 4.74873 3.47448 0 0 0 + 378 444 2 0.20964 0.20631 3.65922 2.38482 0 0 0 + 379 444 3 0.03193 5.74906 1.64126 13.27894 0 0 0 + 380 444 4 -0.39965 5.74933 0.96366 14.53304 0 0 0 + 381 444 1 0.05269 5.05775 2.48272 13.31880 0 0 0 + 382 444 1 0.05269 6.74849 2.01315 13.05234 0 0 0 + 383 444 1 0.05269 5.43187 0.95557 12.49248 0 0 0 + 384 444 2 0.20964 6.42516 0.25912 14.43537 0 0 0 + + +Bonds + + 1 1 1 2 + 2 3 1 3 + 3 3 1 4 + 4 3 1 5 + 5 2 2 6 + 6 1 7 8 + 7 3 7 9 + 8 3 7 10 + 9 3 7 11 + 10 2 8 12 + 11 1 13 14 + 12 3 13 15 + 13 3 13 16 + 14 3 13 17 + 15 2 14 18 + 16 1 19 20 + 17 3 19 21 + 18 3 19 22 + 19 3 19 23 + 20 2 20 24 + 21 1 25 26 + 22 3 25 27 + 23 3 25 28 + 24 3 25 29 + 25 2 26 30 + 26 1 31 32 + 27 3 31 33 + 28 3 31 34 + 29 3 31 35 + 30 2 32 36 + 31 1 37 38 + 32 3 37 39 + 33 3 37 40 + 34 3 37 41 + 35 2 38 42 + 36 1 43 44 + 37 3 43 45 + 38 3 43 46 + 39 3 43 47 + 40 2 44 48 + 41 1 49 50 + 42 3 49 51 + 43 3 49 52 + 44 3 49 53 + 45 2 50 54 + 46 1 55 56 + 47 3 55 57 + 48 3 55 58 + 49 3 55 59 + 50 2 56 60 + 51 1 61 62 + 52 3 61 63 + 53 3 61 64 + 54 3 61 65 + 55 2 62 66 + 56 1 67 68 + 57 3 67 69 + 58 3 67 70 + 59 3 67 71 + 60 2 68 72 + 61 1 73 74 + 62 3 73 75 + 63 3 73 76 + 64 3 73 77 + 65 2 74 78 + 66 1 79 80 + 67 3 79 81 + 68 3 79 82 + 69 3 79 83 + 70 2 80 84 + 71 1 85 86 + 72 3 85 87 + 73 3 85 88 + 74 3 85 89 + 75 2 86 90 + 76 1 91 92 + 77 3 91 93 + 78 3 91 94 + 79 3 91 95 + 80 2 92 96 + 81 1 97 98 + 82 3 97 99 + 83 3 97 100 + 84 3 97 101 + 85 2 98 102 + 86 1 103 104 + 87 3 103 105 + 88 3 103 106 + 89 3 103 107 + 90 2 104 108 + 91 1 109 110 + 92 3 109 111 + 93 3 109 112 + 94 3 109 113 + 95 2 110 114 + 96 1 115 116 + 97 3 115 117 + 98 3 115 118 + 99 3 115 119 + 100 2 116 120 + 101 1 121 122 + 102 3 121 123 + 103 3 121 124 + 104 3 121 125 + 105 2 122 126 + 106 1 127 128 + 107 3 127 129 + 108 3 127 130 + 109 3 127 131 + 110 2 128 132 + 111 1 133 134 + 112 3 133 135 + 113 3 133 136 + 114 3 133 137 + 115 2 134 138 + 116 1 139 140 + 117 3 139 141 + 118 3 139 142 + 119 3 139 143 + 120 2 140 144 + 121 1 145 146 + 122 3 145 147 + 123 3 145 148 + 124 3 145 149 + 125 2 146 150 + 126 1 151 152 + 127 3 151 153 + 128 3 151 154 + 129 3 151 155 + 130 2 152 156 + 131 1 157 158 + 132 3 157 159 + 133 3 157 160 + 134 3 157 161 + 135 2 158 162 + 136 1 163 164 + 137 3 163 165 + 138 3 163 166 + 139 3 163 167 + 140 2 164 168 + 141 1 169 170 + 142 3 169 171 + 143 3 169 172 + 144 3 169 173 + 145 2 170 174 + 146 1 175 176 + 147 3 175 177 + 148 3 175 178 + 149 3 175 179 + 150 2 176 180 + 151 1 181 182 + 152 3 181 183 + 153 3 181 184 + 154 3 181 185 + 155 2 182 186 + 156 1 187 188 + 157 3 187 189 + 158 3 187 190 + 159 3 187 191 + 160 2 188 192 + 161 1 193 194 + 162 3 193 195 + 163 3 193 196 + 164 3 193 197 + 165 2 194 198 + 166 1 199 200 + 167 3 199 201 + 168 3 199 202 + 169 3 199 203 + 170 2 200 204 + 171 1 205 206 + 172 3 205 207 + 173 3 205 208 + 174 3 205 209 + 175 2 206 210 + 176 1 211 212 + 177 3 211 213 + 178 3 211 214 + 179 3 211 215 + 180 2 212 216 + 181 1 217 218 + 182 3 217 219 + 183 3 217 220 + 184 3 217 221 + 185 2 218 222 + 186 1 223 224 + 187 3 223 225 + 188 3 223 226 + 189 3 223 227 + 190 2 224 228 + 191 1 229 230 + 192 3 229 231 + 193 3 229 232 + 194 3 229 233 + 195 2 230 234 + 196 1 235 236 + 197 3 235 237 + 198 3 235 238 + 199 3 235 239 + 200 2 236 240 + 201 1 241 242 + 202 3 241 243 + 203 3 241 244 + 204 3 241 245 + 205 2 242 246 + 206 1 247 248 + 207 3 247 249 + 208 3 247 250 + 209 3 247 251 + 210 2 248 252 + 211 1 253 254 + 212 3 253 255 + 213 3 253 256 + 214 3 253 257 + 215 2 254 258 + 216 1 259 260 + 217 3 259 261 + 218 3 259 262 + 219 3 259 263 + 220 2 260 264 + 221 1 265 266 + 222 3 265 267 + 223 3 265 268 + 224 3 265 269 + 225 2 266 270 + 226 1 271 272 + 227 3 271 273 + 228 3 271 274 + 229 3 271 275 + 230 2 272 276 + 231 1 277 278 + 232 3 277 279 + 233 3 277 280 + 234 3 277 281 + 235 2 278 282 + 236 1 283 284 + 237 3 283 285 + 238 3 283 286 + 239 3 283 287 + 240 2 284 288 + 241 1 289 290 + 242 3 289 291 + 243 3 289 292 + 244 3 289 293 + 245 2 290 294 + 246 1 295 296 + 247 3 295 297 + 248 3 295 298 + 249 3 295 299 + 250 2 296 300 + 251 1 301 302 + 252 3 301 303 + 253 3 301 304 + 254 3 301 305 + 255 2 302 306 + 256 1 307 308 + 257 3 307 309 + 258 3 307 310 + 259 3 307 311 + 260 2 308 312 + 261 1 313 314 + 262 3 313 315 + 263 3 313 316 + 264 3 313 317 + 265 2 314 318 + 266 1 319 320 + 267 3 319 321 + 268 3 319 322 + 269 3 319 323 + 270 2 320 324 + 271 1 325 326 + 272 3 325 327 + 273 3 325 328 + 274 3 325 329 + 275 2 326 330 + 276 1 331 332 + 277 3 331 333 + 278 3 331 334 + 279 3 331 335 + 280 2 332 336 + 281 1 337 338 + 282 3 337 339 + 283 3 337 340 + 284 3 337 341 + 285 2 338 342 + 286 1 343 344 + 287 3 343 345 + 288 3 343 346 + 289 3 343 347 + 290 2 344 348 + 291 1 349 350 + 292 3 349 351 + 293 3 349 352 + 294 3 349 353 + 295 2 350 354 + 296 1 355 356 + 297 3 355 357 + 298 3 355 358 + 299 3 355 359 + 300 2 356 360 + 301 1 361 362 + 302 3 361 363 + 303 3 361 364 + 304 3 361 365 + 305 2 362 366 + 306 1 367 368 + 307 3 367 369 + 308 3 367 370 + 309 3 367 371 + 310 2 368 372 + 311 1 373 374 + 312 3 373 375 + 313 3 373 376 + 314 3 373 377 + 315 2 374 378 + 316 1 379 380 + 317 3 379 381 + 318 3 379 382 + 319 3 379 383 + 320 2 380 384 + +Angles + + 1 2 3 1 2 + 2 2 4 1 2 + 3 2 4 1 3 + 4 2 5 1 2 + 5 2 5 1 3 + 6 2 5 1 4 + 7 1 6 2 1 + 8 1 7 8 12 + 9 2 8 7 10 + 10 2 8 7 11 + 11 2 9 7 8 + 12 2 9 7 10 + 13 2 9 7 11 + 14 2 11 7 10 + 15 2 15 13 14 + 16 2 16 13 14 + 17 2 16 13 15 + 18 2 17 13 14 + 19 2 17 13 15 + 20 2 17 13 16 + 21 1 18 14 13 + 22 2 21 19 20 + 23 2 22 19 20 + 24 2 22 19 21 + 25 2 23 19 20 + 26 2 23 19 21 + 27 2 23 19 22 + 28 1 24 20 19 + 29 2 27 25 26 + 30 2 28 25 26 + 31 2 28 25 27 + 32 2 29 25 26 + 33 2 29 25 27 + 34 2 29 25 28 + 35 1 30 26 25 + 36 2 33 31 32 + 37 2 34 31 32 + 38 2 34 31 33 + 39 2 35 31 32 + 40 2 35 31 33 + 41 2 35 31 34 + 42 1 36 32 31 + 43 2 39 37 38 + 44 2 40 37 38 + 45 2 40 37 39 + 46 2 41 37 38 + 47 2 41 37 39 + 48 2 41 37 40 + 49 1 42 38 37 + 50 2 45 43 44 + 51 2 46 43 44 + 52 2 46 43 45 + 53 2 47 43 44 + 54 2 47 43 45 + 55 2 47 43 46 + 56 1 48 44 43 + 57 2 51 49 50 + 58 2 52 49 50 + 59 2 52 49 51 + 60 2 53 49 50 + 61 2 53 49 51 + 62 2 53 49 52 + 63 1 54 50 49 + 64 2 57 55 56 + 65 2 58 55 56 + 66 2 58 55 57 + 67 2 59 55 56 + 68 2 59 55 57 + 69 2 59 55 58 + 70 1 60 56 55 + 71 2 63 61 62 + 72 2 64 61 62 + 73 2 64 61 63 + 74 2 65 61 62 + 75 2 65 61 63 + 76 2 65 61 64 + 77 1 66 62 61 + 78 2 69 67 68 + 79 2 70 67 68 + 80 2 70 67 69 + 81 2 71 67 68 + 82 2 71 67 69 + 83 2 71 67 70 + 84 1 72 68 67 + 85 2 75 73 74 + 86 2 76 73 74 + 87 2 76 73 75 + 88 2 77 73 74 + 89 2 77 73 75 + 90 2 77 73 76 + 91 1 78 74 73 + 92 2 81 79 80 + 93 2 82 79 80 + 94 2 82 79 81 + 95 2 83 79 80 + 96 2 83 79 81 + 97 2 83 79 82 + 98 1 84 80 79 + 99 2 87 85 86 + 100 2 88 85 86 + 101 2 88 85 87 + 102 2 89 85 86 + 103 2 89 85 87 + 104 2 89 85 88 + 105 1 90 86 85 + 106 2 93 91 92 + 107 2 94 91 92 + 108 2 94 91 93 + 109 2 95 91 92 + 110 2 95 91 93 + 111 2 95 91 94 + 112 1 96 92 91 + 113 1 97 98 102 + 114 2 98 97 100 + 115 2 98 97 101 + 116 2 99 97 98 + 117 2 99 97 100 + 118 2 99 97 101 + 119 2 101 97 100 + 120 2 105 103 104 + 121 2 106 103 104 + 122 2 106 103 105 + 123 2 107 103 104 + 124 2 107 103 105 + 125 2 107 103 106 + 126 1 108 104 103 + 127 2 111 109 110 + 128 2 112 109 110 + 129 2 112 109 111 + 130 2 113 109 110 + 131 2 113 109 111 + 132 2 113 109 112 + 133 1 114 110 109 + 134 2 117 115 116 + 135 2 118 115 116 + 136 2 118 115 117 + 137 2 119 115 116 + 138 2 119 115 117 + 139 2 119 115 118 + 140 1 120 116 115 + 141 2 123 121 122 + 142 2 124 121 122 + 143 2 124 121 123 + 144 2 125 121 122 + 145 2 125 121 123 + 146 2 125 121 124 + 147 1 126 122 121 + 148 2 129 127 128 + 149 2 130 127 128 + 150 2 130 127 129 + 151 2 131 127 128 + 152 2 131 127 129 + 153 2 131 127 130 + 154 1 132 128 127 + 155 2 135 133 134 + 156 2 136 133 134 + 157 2 136 133 135 + 158 2 137 133 134 + 159 2 137 133 135 + 160 2 137 133 136 + 161 1 138 134 133 + 162 2 141 139 140 + 163 2 142 139 140 + 164 2 142 139 141 + 165 2 143 139 140 + 166 2 143 139 141 + 167 2 143 139 142 + 168 1 144 140 139 + 169 2 147 145 146 + 170 2 148 145 146 + 171 2 148 145 147 + 172 2 149 145 146 + 173 2 149 145 147 + 174 2 149 145 148 + 175 1 150 146 145 + 176 2 153 151 152 + 177 2 154 151 152 + 178 2 154 151 153 + 179 2 155 151 152 + 180 2 155 151 153 + 181 2 155 151 154 + 182 1 156 152 151 + 183 2 159 157 158 + 184 2 160 157 158 + 185 2 160 157 159 + 186 2 161 157 158 + 187 2 161 157 159 + 188 2 161 157 160 + 189 1 162 158 157 + 190 2 165 163 164 + 191 2 166 163 164 + 192 2 166 163 165 + 193 2 167 163 164 + 194 2 167 163 165 + 195 2 167 163 166 + 196 1 168 164 163 + 197 2 171 169 170 + 198 2 172 169 170 + 199 2 172 169 171 + 200 2 173 169 170 + 201 2 173 169 171 + 202 2 173 169 172 + 203 1 174 170 169 + 204 2 177 175 176 + 205 2 178 175 176 + 206 2 178 175 177 + 207 2 179 175 176 + 208 2 179 175 177 + 209 2 179 175 178 + 210 1 180 176 175 + 211 2 183 181 182 + 212 2 184 181 182 + 213 2 184 181 183 + 214 2 185 181 182 + 215 2 185 181 183 + 216 2 185 181 184 + 217 1 186 182 181 + 218 2 189 187 188 + 219 2 190 187 188 + 220 2 190 187 189 + 221 2 191 187 188 + 222 2 191 187 189 + 223 2 191 187 190 + 224 1 192 188 187 + 225 2 195 193 194 + 226 2 196 193 194 + 227 2 196 193 195 + 228 2 197 193 194 + 229 2 197 193 195 + 230 2 197 193 196 + 231 1 198 194 193 + 232 2 201 199 200 + 233 2 202 199 200 + 234 2 202 199 201 + 235 2 203 199 200 + 236 2 203 199 201 + 237 2 203 199 202 + 238 1 204 200 199 + 239 2 207 205 206 + 240 2 208 205 206 + 241 2 208 205 207 + 242 2 209 205 206 + 243 2 209 205 207 + 244 2 209 205 208 + 245 1 210 206 205 + 246 2 213 211 212 + 247 2 214 211 212 + 248 2 214 211 213 + 249 2 215 211 212 + 250 2 215 211 213 + 251 2 215 211 214 + 252 1 216 212 211 + 253 2 219 217 218 + 254 2 220 217 218 + 255 2 220 217 219 + 256 2 221 217 218 + 257 2 221 217 219 + 258 2 221 217 220 + 259 1 222 218 217 + 260 2 225 223 224 + 261 2 226 223 224 + 262 2 226 223 225 + 263 2 227 223 224 + 264 2 227 223 225 + 265 2 227 223 226 + 266 1 228 224 223 + 267 2 231 229 230 + 268 2 232 229 230 + 269 2 232 229 231 + 270 2 233 229 230 + 271 2 233 229 231 + 272 2 233 229 232 + 273 1 234 230 229 + 274 2 237 235 236 + 275 2 238 235 236 + 276 2 238 235 237 + 277 2 239 235 236 + 278 2 239 235 237 + 279 2 239 235 238 + 280 1 240 236 235 + 281 2 243 241 242 + 282 2 244 241 242 + 283 2 244 241 243 + 284 2 245 241 242 + 285 2 245 241 243 + 286 2 245 241 244 + 287 1 246 242 241 + 288 2 249 247 248 + 289 2 250 247 248 + 290 2 250 247 249 + 291 2 251 247 248 + 292 2 251 247 249 + 293 2 251 247 250 + 294 1 252 248 247 + 295 2 255 253 254 + 296 2 256 253 254 + 297 2 256 253 255 + 298 2 257 253 254 + 299 2 257 253 255 + 300 2 257 253 256 + 301 1 258 254 253 + 302 2 261 259 260 + 303 2 262 259 260 + 304 2 262 259 261 + 305 2 263 259 260 + 306 2 263 259 261 + 307 2 263 259 262 + 308 1 264 260 259 + 309 2 267 265 266 + 310 2 268 265 266 + 311 2 268 265 267 + 312 2 269 265 266 + 313 2 269 265 267 + 314 2 269 265 268 + 315 1 270 266 265 + 316 2 273 271 272 + 317 2 274 271 272 + 318 2 274 271 273 + 319 2 275 271 272 + 320 2 275 271 273 + 321 2 275 271 274 + 322 1 276 272 271 + 323 2 279 277 278 + 324 2 280 277 278 + 325 2 280 277 279 + 326 2 281 277 278 + 327 2 281 277 279 + 328 2 281 277 280 + 329 1 282 278 277 + 330 2 285 283 284 + 331 2 286 283 284 + 332 2 286 283 285 + 333 2 287 283 284 + 334 2 287 283 285 + 335 2 287 283 286 + 336 1 288 284 283 + 337 2 291 289 290 + 338 2 292 289 290 + 339 2 292 289 291 + 340 2 293 289 290 + 341 2 293 289 291 + 342 2 293 289 292 + 343 1 294 290 289 + 344 2 297 295 296 + 345 2 298 295 296 + 346 2 298 295 297 + 347 2 299 295 296 + 348 2 299 295 297 + 349 2 299 295 298 + 350 1 300 296 295 + 351 2 303 301 302 + 352 2 304 301 302 + 353 2 304 301 303 + 354 2 305 301 302 + 355 2 305 301 303 + 356 2 305 301 304 + 357 1 306 302 301 + 358 2 309 307 308 + 359 2 310 307 308 + 360 2 310 307 309 + 361 2 311 307 308 + 362 2 311 307 309 + 363 2 311 307 310 + 364 1 312 308 307 + 365 2 315 313 314 + 366 2 316 313 314 + 367 2 316 313 315 + 368 2 317 313 314 + 369 2 317 313 315 + 370 2 317 313 316 + 371 1 318 314 313 + 372 2 321 319 320 + 373 2 322 319 320 + 374 2 322 319 321 + 375 2 323 319 320 + 376 2 323 319 321 + 377 2 323 319 322 + 378 1 324 320 319 + 379 2 327 325 326 + 380 2 328 325 326 + 381 2 328 325 327 + 382 2 329 325 326 + 383 2 329 325 327 + 384 2 329 325 328 + 385 1 330 326 325 + 386 2 333 331 332 + 387 2 334 331 332 + 388 2 334 331 333 + 389 2 335 331 332 + 390 2 335 331 333 + 391 2 335 331 334 + 392 1 336 332 331 + 393 2 339 337 338 + 394 2 340 337 338 + 395 2 340 337 339 + 396 2 341 337 338 + 397 2 341 337 339 + 398 2 341 337 340 + 399 1 342 338 337 + 400 2 345 343 344 + 401 2 346 343 344 + 402 2 346 343 345 + 403 2 347 343 344 + 404 2 347 343 345 + 405 2 347 343 346 + 406 1 348 344 343 + 407 2 351 349 350 + 408 2 352 349 350 + 409 2 352 349 351 + 410 2 353 349 350 + 411 2 353 349 351 + 412 2 353 349 352 + 413 1 354 350 349 + 414 2 357 355 356 + 415 2 358 355 356 + 416 2 358 355 357 + 417 2 359 355 356 + 418 2 359 355 357 + 419 2 359 355 358 + 420 1 360 356 355 + 421 2 363 361 362 + 422 2 364 361 362 + 423 2 364 361 363 + 424 2 365 361 362 + 425 2 365 361 363 + 426 2 365 361 364 + 427 1 366 362 361 + 428 2 369 367 368 + 429 2 370 367 368 + 430 2 370 367 369 + 431 2 371 367 368 + 432 2 371 367 369 + 433 2 371 367 370 + 434 1 372 368 367 + 435 2 375 373 374 + 436 2 376 373 374 + 437 2 376 373 375 + 438 2 377 373 374 + 439 2 377 373 375 + 440 2 377 373 376 + 441 1 378 374 373 + 442 2 381 379 380 + 443 2 382 379 380 + 444 2 382 379 381 + 445 2 383 379 380 + 446 2 383 379 381 + 447 2 383 379 382 + 448 1 384 380 379 + +Dihedrals + + 1 1 6 2 1 3 + 2 1 6 2 1 4 + 3 1 6 2 1 5 + 4 1 9 7 8 12 + 5 1 12 8 7 10 + 6 1 12 8 7 11 + 7 1 18 14 13 15 + 8 1 18 14 13 16 + 9 1 18 14 13 17 + 10 1 24 20 19 21 + 11 1 24 20 19 22 + 12 1 24 20 19 23 + 13 1 30 26 25 27 + 14 1 30 26 25 28 + 15 1 30 26 25 29 + 16 1 36 32 31 33 + 17 1 36 32 31 34 + 18 1 36 32 31 35 + 19 1 42 38 37 39 + 20 1 42 38 37 40 + 21 1 42 38 37 41 + 22 1 48 44 43 45 + 23 1 48 44 43 46 + 24 1 48 44 43 47 + 25 1 54 50 49 51 + 26 1 54 50 49 52 + 27 1 54 50 49 53 + 28 1 60 56 55 57 + 29 1 60 56 55 58 + 30 1 60 56 55 59 + 31 1 66 62 61 63 + 32 1 66 62 61 64 + 33 1 66 62 61 65 + 34 1 72 68 67 69 + 35 1 72 68 67 70 + 36 1 72 68 67 71 + 37 1 78 74 73 75 + 38 1 78 74 73 76 + 39 1 78 74 73 77 + 40 1 84 80 79 81 + 41 1 84 80 79 82 + 42 1 84 80 79 83 + 43 1 90 86 85 87 + 44 1 90 86 85 88 + 45 1 90 86 85 89 + 46 1 96 92 91 93 + 47 1 96 92 91 94 + 48 1 96 92 91 95 + 49 1 99 97 98 102 + 50 1 102 98 97 100 + 51 1 102 98 97 101 + 52 1 108 104 103 105 + 53 1 108 104 103 106 + 54 1 108 104 103 107 + 55 1 114 110 109 111 + 56 1 114 110 109 112 + 57 1 114 110 109 113 + 58 1 120 116 115 117 + 59 1 120 116 115 118 + 60 1 120 116 115 119 + 61 1 126 122 121 123 + 62 1 126 122 121 124 + 63 1 126 122 121 125 + 64 1 132 128 127 129 + 65 1 132 128 127 130 + 66 1 132 128 127 131 + 67 1 138 134 133 135 + 68 1 138 134 133 136 + 69 1 138 134 133 137 + 70 1 144 140 139 141 + 71 1 144 140 139 142 + 72 1 144 140 139 143 + 73 1 150 146 145 147 + 74 1 150 146 145 148 + 75 1 150 146 145 149 + 76 1 156 152 151 153 + 77 1 156 152 151 154 + 78 1 156 152 151 155 + 79 1 162 158 157 159 + 80 1 162 158 157 160 + 81 1 162 158 157 161 + 82 1 168 164 163 165 + 83 1 168 164 163 166 + 84 1 168 164 163 167 + 85 1 174 170 169 171 + 86 1 174 170 169 172 + 87 1 174 170 169 173 + 88 1 180 176 175 177 + 89 1 180 176 175 178 + 90 1 180 176 175 179 + 91 1 186 182 181 183 + 92 1 186 182 181 184 + 93 1 186 182 181 185 + 94 1 192 188 187 189 + 95 1 192 188 187 190 + 96 1 192 188 187 191 + 97 1 198 194 193 195 + 98 1 198 194 193 196 + 99 1 198 194 193 197 + 100 1 204 200 199 201 + 101 1 204 200 199 202 + 102 1 204 200 199 203 + 103 1 210 206 205 207 + 104 1 210 206 205 208 + 105 1 210 206 205 209 + 106 1 216 212 211 213 + 107 1 216 212 211 214 + 108 1 216 212 211 215 + 109 1 222 218 217 219 + 110 1 222 218 217 220 + 111 1 222 218 217 221 + 112 1 228 224 223 225 + 113 1 228 224 223 226 + 114 1 228 224 223 227 + 115 1 234 230 229 231 + 116 1 234 230 229 232 + 117 1 234 230 229 233 + 118 1 240 236 235 237 + 119 1 240 236 235 238 + 120 1 240 236 235 239 + 121 1 246 242 241 243 + 122 1 246 242 241 244 + 123 1 246 242 241 245 + 124 1 252 248 247 249 + 125 1 252 248 247 250 + 126 1 252 248 247 251 + 127 1 258 254 253 255 + 128 1 258 254 253 256 + 129 1 258 254 253 257 + 130 1 264 260 259 261 + 131 1 264 260 259 262 + 132 1 264 260 259 263 + 133 1 270 266 265 267 + 134 1 270 266 265 268 + 135 1 270 266 265 269 + 136 1 276 272 271 273 + 137 1 276 272 271 274 + 138 1 276 272 271 275 + 139 1 282 278 277 279 + 140 1 282 278 277 280 + 141 1 282 278 277 281 + 142 1 288 284 283 285 + 143 1 288 284 283 286 + 144 1 288 284 283 287 + 145 1 294 290 289 291 + 146 1 294 290 289 292 + 147 1 294 290 289 293 + 148 1 300 296 295 297 + 149 1 300 296 295 298 + 150 1 300 296 295 299 + 151 1 306 302 301 303 + 152 1 306 302 301 304 + 153 1 306 302 301 305 + 154 1 312 308 307 309 + 155 1 312 308 307 310 + 156 1 312 308 307 311 + 157 1 318 314 313 315 + 158 1 318 314 313 316 + 159 1 318 314 313 317 + 160 1 324 320 319 321 + 161 1 324 320 319 322 + 162 1 324 320 319 323 + 163 1 330 326 325 327 + 164 1 330 326 325 328 + 165 1 330 326 325 329 + 166 1 336 332 331 333 + 167 1 336 332 331 334 + 168 1 336 332 331 335 + 169 1 342 338 337 339 + 170 1 342 338 337 340 + 171 1 342 338 337 341 + 172 1 348 344 343 345 + 173 1 348 344 343 346 + 174 1 348 344 343 347 + 175 1 354 350 349 351 + 176 1 354 350 349 352 + 177 1 354 350 349 353 + 178 1 360 356 355 357 + 179 1 360 356 355 358 + 180 1 360 356 355 359 + 181 1 366 362 361 363 + 182 1 366 362 361 364 + 183 1 366 362 361 365 + 184 1 372 368 367 369 + 185 1 372 368 367 370 + 186 1 372 368 367 371 + 187 1 378 374 373 375 + 188 1 378 374 373 376 + 189 1 378 374 373 377 + 190 1 384 380 379 381 + 191 1 384 380 379 382 + 192 1 384 380 379 383 + +Impropers + diff --git a/examples/dreiding/in.dreiding b/examples/dreiding/in.dreiding new file mode 100644 index 0000000000..4b811248d4 --- /dev/null +++ b/examples/dreiding/in.dreiding @@ -0,0 +1,39 @@ +units real +atom_style full +boundary p p p +dielectric 1 +special_bonds lj/coul 0.0 0.0 1.0 + +pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5 +bond_style harmonic +angle_style harmonic +dihedral_style harmonic +improper_style none +kspace_style pppm 0.001 + +read_data data.dreiding + +pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478 +pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478 +pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677 +pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103 +pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478 +pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677 +pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103 +pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877 +pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302 +pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727 +pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4 +pair_modify mix arithmetic +neighbor 2.0 multi +neigh_modify every 2 delay 4 check yes +variable input index in.ch3oh.box.dreiding +variable sname index ch3oh.box.dreiding + +compute hb all pair hbond/dreiding/lj +variable C_hbond equal c_hb[1] #number hbonds +variable E_hbond equal c_hb[2] #hbond energy +thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol +thermo_modify line multi format float %14.6f + +run 0 diff --git a/examples/dreiding/log.dreiding.11Oct11.linux.1 b/examples/dreiding/log.dreiding.11Oct11.linux.1 new file mode 100644 index 0000000000..74267f98cc --- /dev/null +++ b/examples/dreiding/log.dreiding.11Oct11.linux.1 @@ -0,0 +1,97 @@ +LAMMPS (10 Oct 2011) +units real +atom_style full +boundary p p p +dielectric 1 +special_bonds lj/coul 0.0 0.0 1.0 + +pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5 +bond_style harmonic +angle_style harmonic +dihedral_style harmonic +improper_style none +kspace_style pppm 0.001 + +read_data data.dreiding + 4 = max bonds/atom + 6 = max angles/atom + 3 = max dihedrals/atom + 0 = max impropers/atom + orthogonal box = (0 0 0) to (19.9969 19.1282 19.4697) + 1 by 1 by 1 processor grid + 384 atoms + 320 bonds + 448 angles + 192 dihedrals + 0 impropers + 4 = max # of 1-2 neighbors + 3 = max # of 1-3 neighbors + 5 = max # of special neighbors + +pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478 +pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478 +pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677 +pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103 +pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478 +pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677 +pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103 +pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877 +pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302 +pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727 +pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4 +pair_modify mix arithmetic +neighbor 2.0 multi +neigh_modify every 2 delay 4 check yes +variable input index in.ch3oh.box.dreiding +variable sname index ch3oh.box.dreiding + +compute hb all pair hbond/dreiding/lj +variable C_hbond equal c_hb[1] #number hbonds +variable E_hbond equal c_hb[2] #hbond energy +thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol +thermo_modify line multi format float %14.6f + +run 0 +WARNING: No fixes defined, atoms won't move (verlet.cpp:52) +PPPM initialization ... +WARNING: System is not charge neutral, net charge = -0.00064 (pppm.cpp:204) + G vector = 0.142075 + grid = 3 3 3 + stencil order = 5 + RMS precision = 0.000329493 + using double precision FFTs + brick FFT buffer size/proc = 512 27 576 +Memory usage per processor = 7.9487 Mbytes +---------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- +TotEng = 113.723443 KinEng = 0.000000 Temp = 0.000000 +PotEng = 113.723443 E_bond = 0.535673 E_angle = 1.281880 +E_dihed = 1.232497 E_impro = 0.000000 E_vdwl = -125.381324 +E_coul = 597.224193 E_long = -361.169476 E_hbond = -69.322152 +C_hbond = 235.000000 Press = -847.552598 Volume = 7447.236335 +Loop time of 0 on 1 procs for 0 steps with 384 atoms + +Pair time (%) = 0 (0) +Bond time (%) = 0 (0) +Kspce time (%) = 0 (0) +Neigh time (%) = 0 (0) +Comm time (%) = 0 (0) +Outpt time (%) = 0 (0) +Other time (%) = 0 (0) + +FFT time (% of Kspce) = 0 (0) +FFT Gflps 3d (1d only) = 0 0 + +Nlocal: 384 ave 384 max 384 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 4637 ave 4637 max 4637 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 101854 ave 101854 max 101854 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 203708 ave 203708 max 203708 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 203708 +Ave neighs/atom = 530.49 +Ave special neighs/atom = 4 +Neighbor list builds = 0 +Dangerous builds = 0 diff --git a/examples/dreiding/log.dreiding.11Oct11.linux.4 b/examples/dreiding/log.dreiding.11Oct11.linux.4 new file mode 100644 index 0000000000..3f0ac1c40d --- /dev/null +++ b/examples/dreiding/log.dreiding.11Oct11.linux.4 @@ -0,0 +1,121 @@ +LAMMPS (10 Oct 2011) +units real +atom_style full +boundary p p p +dielectric 1 +special_bonds lj/coul 0.0 0.0 1.0 + +pair_style hybrid/overlay hbond/dreiding/lj 2 6 6.5 90 lj/cut/coul/long 8.50000 11.5 +bond_style harmonic +angle_style harmonic +dihedral_style harmonic +improper_style none +kspace_style pppm 0.001 + +read_data data.dreiding + 4 = max bonds/atom + 6 = max angles/atom + 3 = max dihedrals/atom + 0 = max impropers/atom + orthogonal box = (0 0 0) to (19.9969 19.1282 19.4697) + 2 by 1 by 2 processor grid + 384 atoms + 320 bonds + 448 angles + 192 dihedrals + 0 impropers + 4 = max # of 1-2 neighbors + 3 = max # of 1-3 neighbors + 5 = max # of special neighbors + +pair_coeff 1 1 lj/cut/coul/long 0.015200000256300 2.846421344984478 +pair_coeff 1 2 lj/cut/coul/long 0.001232882795416 2.846421344984478 +pair_coeff 1 3 lj/cut/coul/long 0.038019995160237 3.159705878878677 +pair_coeff 1 4 lj/cut/coul/long 0.038139744011598 2.939787518071103 +pair_coeff 2 2 lj/cut/coul/long 9.99999974737875e-05 2.846421344984478 +pair_coeff 2 3 lj/cut/coul/long 0.003083828758188 3.159705878878677 +pair_coeff 2 4 lj/cut/coul/long 0.003093541672406 2.939787518071103 +pair_coeff 3 3 lj/cut/coul/long 0.095100000500679 3.472990412772877 +pair_coeff 3 4 lj/cut/coul/long 0.095399530150179 3.253072051965302 +pair_coeff 4 4 lj/cut/coul/long 0.095700003206730 3.033153691157727 +pair_coeff 4 4 hbond/dreiding/lj 2 i 0.4000E+01 2.750000000000000 4 +pair_modify mix arithmetic +neighbor 2.0 multi +neigh_modify every 2 delay 4 check yes +variable input index in.ch3oh.box.dreiding +variable sname index ch3oh.box.dreiding + +compute hb all pair hbond/dreiding/lj +variable C_hbond equal c_hb[1] #number hbonds +variable E_hbond equal c_hb[2] #hbond energy +thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong v_E_hbond v_C_hbond press vol +thermo_modify line multi format float %14.6f + +run 0 +WARNING: No fixes defined, atoms won't move (verlet.cpp:52) +PPPM initialization ... +WARNING: System is not charge neutral, net charge = -0.00064 (pppm.cpp:204) + G vector = 0.142075 + grid = 3 3 3 + stencil order = 5 + RMS precision = 0.000329493 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.143211 + grid = 3 3 3 + stencil order = 4 + RMS precision = 0.000315601 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.140124 + grid = 3 3 3 + stencil order = 3 + RMS precision = 0.000354326 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.127333 + grid = 3 3 3 + stencil order = 2 + RMS precision = 0.00055716 + using double precision FFTs +WARNING: Reducing PPPM order b/c stencil extends beyond neighbor processor (pppm.cpp:216) + G vector = 0.113516 + grid = 9 9 9 + stencil order = 1 + RMS precision = 0.000864991 + using double precision FFTs + brick FFT buffer size/proc = 360 243 360 +Memory usage per processor = 6.52575 Mbytes +---------------- Step 0 ----- CPU = 0.0000 (sec) ---------------- +TotEng = 118.484313 KinEng = 0.000000 Temp = 0.000000 +PotEng = 118.484313 E_bond = 0.535673 E_angle = 1.281880 +E_dihed = 1.232497 E_impro = 0.000000 E_vdwl = -125.381324 +E_coul = 529.430008 E_long = -288.614421 E_hbond = -69.322152 +C_hbond = 235.000000 Press = -803.848888 Volume = 7447.236335 +Loop time of 1.43051e-06 on 4 procs for 0 steps with 384 atoms + +Pair time (%) = 0 (0) +Bond time (%) = 0 (0) +Kspce time (%) = 0 (0) +Neigh time (%) = 0 (0) +Comm time (%) = 0 (0) +Outpt time (%) = 0 (0) +Other time (%) = 1.43051e-06 (100) + +FFT time (% of Kspce) = 0 (0) +FFT Gflps 3d (1d only) = 0 0 + +Nlocal: 96 ave 104 max 87 min +Histogram: 1 1 0 0 0 0 0 0 0 2 +Nghost: 3063.25 ave 3108 max 3024 min +Histogram: 1 0 1 0 0 0 1 0 0 1 +Neighs: 25463.5 ave 28799 max 22471 min +Histogram: 1 0 0 1 0 1 0 0 0 1 +FullNghs: 50927 ave 55516 max 46073 min +Histogram: 1 1 0 0 0 0 0 0 0 2 + +Total # of neighbors = 203708 +Ave neighs/atom = 530.49 +Ave special neighs/atom = 4 +Neighbor list builds = 0 +Dangerous builds = 0 diff --git a/lib/cuda/Makefile.defaults b/lib/cuda/Makefile.defaults index 3f39f7d606..ea0c53a349 100644 --- a/lib/cuda/Makefile.defaults +++ b/lib/cuda/Makefile.defaults @@ -3,7 +3,7 @@ precision ?= 1 #GPU architecture (compute capability): 13, 20, 21 -arch ?= 20 +arch ?= 21 #Using cufft (should not be changed) cufft ?= 1 diff --git a/lib/cuda/Makefile.lammps b/lib/cuda/Makefile.lammps index 172fbc91ec..711e827a65 100644 --- a/lib/cuda/Makefile.lammps +++ b/lib/cuda/Makefile.lammps @@ -1,6 +1,6 @@ # Settings that the LAMMPS build will import when this package library is used - CUDA_FLAGS = -I/usr/local/cuda/include -I../../lib/cuda -DUNIX -DFFT_CUFFT -DCUDA_PRECISION=1 -DCUDA_ARCH=20 - CUDA_USRLIB_CONDITIONAL = -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcufft +CUDA_FLAGS := -I/usr/local/cuda/include -DUNIX -DFFT_CUFFT -DCUDA_PRECISION=1 -DCUDA_ARCH=20 +CUDA_USRLIB_CONDITIONAL := -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcufft user-cuda_SYSINC = ${CUDA_FLAGS} user-cuda_SYSLIB = -lcuda -lcudart -lrt diff --git a/src/USER-CUDA/cuda_common.h b/lib/cuda/cuda_common.h similarity index 100% rename from src/USER-CUDA/cuda_common.h rename to lib/cuda/cuda_common.h diff --git a/lib/cuda/cuda_pair.cu b/lib/cuda/cuda_pair.cu index 531db7e2b3..b7b2523529 100644 --- a/lib/cuda/cuda_pair.cu +++ b/lib/cuda/cuda_pair.cu @@ -36,6 +36,9 @@ enum COUL_FORCES {COUL_NONE,COUL_CHARMM,COUL_CHARMM_IMPLICIT,COUL_CUT,COUL_LONG, #define DATA_V_RADIUS 512 #define DATA_OMEGA_RMASS 1024 +#define SBBITS 30 +#define NEIGHMASK 0x3FFFFFFF + #define MY_PREFIX cuda_pair #define IncludeCommonNeigh #include "cuda_shared.h" @@ -858,6 +861,9 @@ void Cuda_Pair_PostKernel_AllStyles(cuda_shared_data* sdata, dim3& grid, int& sh #include "cuda_pair_kernel.cu" +#include "pair_manybody_const.h" +#include "pair_tersoff_cuda.cu" +#include "pair_sw_cuda.cu" void Cuda_Pair_UpdateNmax(cuda_shared_data* sdata) { diff --git a/lib/cuda/cuda_pair_kernel.cu b/lib/cuda/cuda_pair_kernel.cu index fe7a38a782..35a0ef1f1a 100644 --- a/lib/cuda/cuda_pair_kernel.cu +++ b/lib/cuda/cuda_pair_kernel.cu @@ -20,7 +20,6 @@ This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ - #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 #define A1 0.254829592 @@ -29,6 +28,10 @@ #define A4 -1.453152027 #define A5 1.061405429 +inline __device__ int sbmask(int j) { + return j >> SBBITS & 3; +} + template __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_atom) { @@ -88,8 +91,8 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at fytmp = F_F(0.0); fztmp = F_F(0.0); - if(coul_type!=COUL_NONE) - qtmp = fetchQ(i); + if(coul_type!=COUL_NONE) + qtmp = fetchQ(i); jnum = _numneigh[i]; jlist = &_neighbors[i]; @@ -103,10 +106,10 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at { fpair=F_F(0.0); j = jlist[jj*_nlocal]; - factor_lj = j<_nall ? F_F(1.0) : _special_lj[j/_nall]; - if(coul_type!=COUL_NONE) - factor_coul = j<_nall ? F_F(1.0) : _special_coul[j/_nall]; - j = j<_nall ? j : j % _nall; + factor_lj = _special_lj[sbmask(j)]; + if(coul_type!=COUL_NONE) + factor_coul = _special_coul[sbmask(j)]; + j &= NEIGHMASK; myxtype = fetchXType(j); delx = xtmp - myxtype.x; @@ -230,7 +233,6 @@ __global__ void Pair_Kernel_TpA(int eflag, int vflag,int eflag_atom,int vflag_at fpair += forcecoul*r2inv; } break; - } } in_cutoff=in_cutoff || in_coul_cutoff; @@ -388,12 +390,12 @@ template nex_mol|sneighlist->nex_group|sneighlist->nex_type; if(exclude) NeighborBuildFullBin_Kernel<1><<>> - (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom); + (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom,sdata->pair.neighall); else NeighborBuildFullBin_Kernel<0><<>> - (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom); + (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff,sdata->pair.use_block_per_atom,sdata->pair.neighall); } //NeighborBuildFullBin_Kernel_Restrict<<>> // (sneighlist->binned_id,sneighlist->bin_nmax,sneighlist->bin_dim[0],sneighlist->bin_dim[1],globcutoff); diff --git a/lib/cuda/neighbor_kernel.cu b/lib/cuda/neighbor_kernel.cu index ad1a6a8fe7..965aa2b1cf 100644 --- a/lib/cuda/neighbor_kernel.cu +++ b/lib/cuda/neighbor_kernel.cu @@ -21,6 +21,8 @@ This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ +#define SBBITS 30 + __global__ void Binning_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,int bin_dim_z, CUDA_FLOAT rez_bin_size_x,CUDA_FLOAT rez_bin_size_y,CUDA_FLOAT rez_bin_size_z) { @@ -109,8 +111,9 @@ __device__ inline int find_special(int3 &n, int* list,int & tag,int3 flag) } template -__global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,CUDA_FLOAT globcutoff,int block_style) +__global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_dim_x,int bin_dim_y,CUDA_FLOAT globcutoff,int block_style, bool neighall) { + int natoms = neighall?_nall:_nlocal; //const bool domol=false; int bin_dim_z=gridDim.y; CUDA_FLOAT* binned_x=(CUDA_FLOAT*) _buffer; @@ -152,7 +155,7 @@ __global__ void NeighborBuildFullBin_Kernel(int* binned_id,int bin_nmax,int bin_ int jnum=0; int itype; - if(i<_nlocal) + if(i _maxneighbors) ((int*)_buffer)[0] = -jnum; - if(i<_nlocal) + if(i0) { if(block_style) - _neighbors[i*_maxneighbors+k]=j+which*_nall; + _neighbors[i*_maxneighbors+k]=j ^ (which << SBBITS); else - _neighbors[i+k*_nlocal]=j+which*_nall; + _neighbors[i+k*_nlocal]=j ^ (which << SBBITS); } else if(which<0) { diff --git a/lib/cuda/pair_manybody_const.h b/lib/cuda/pair_manybody_const.h new file mode 100644 index 0000000000..69bf32aead --- /dev/null +++ b/lib/cuda/pair_manybody_const.h @@ -0,0 +1,16 @@ +/* + * pair_manybody_const.h + * + * Created on: Oct 11, 2011 + * Author: chmu-tph + */ + +#define MANYBODY_NPAIR 3 + +__device__ __constant__ int elem2param[(MANYBODY_NPAIR+1)*(MANYBODY_NPAIR+1)*(MANYBODY_NPAIR+1)]; +__device__ __constant__ int nelements; +__device__ __constant__ int map[MANYBODY_NPAIR+2]; +__device__ __constant__ int* _glob_numneigh_red; //number of neighbors within force cutoff (as opposed to neighbor cutoff) +__device__ __constant__ int* _glob_neighbors_red; //indices of neighbors within force cutoff +__device__ __constant__ int* _glob_neightype_red; //type of neighbors within force cutoff + diff --git a/lib/cuda/pair_sw_cuda.cu b/lib/cuda/pair_sw_cuda.cu new file mode 100644 index 0000000000..f5b0807fcd --- /dev/null +++ b/lib/cuda/pair_sw_cuda.cu @@ -0,0 +1,140 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include + +#include "pair_sw_cuda_cu.h" +__device__ __constant__ ParamSW_Float params_sw[MANYBODY_NPAIR*MANYBODY_NPAIR*MANYBODY_NPAIR]; + +#include "pair_sw_cuda_kernel_nc.cu" + +#include + + +void Cuda_PairSWCuda_Init(cuda_shared_data* sdata,ParamSW_Float* params_host,void* map_host, void* elem2param_host,int nelements_h) +{ + unsigned cuda_ntypes = sdata->atom.ntypes + 1; + X_FLOAT box_size[3] = + { + sdata->domain.subhi[0] - sdata->domain.sublo[0], + sdata->domain.subhi[1] - sdata->domain.sublo[1], + sdata->domain.subhi[2] - sdata->domain.sublo[2] + }; + + cudaMemcpyToSymbol(MY_CONST(box_size) , box_size , sizeof(X_FLOAT)*3); + cudaMemcpyToSymbol(MY_CONST(cuda_ntypes) ,&cuda_ntypes , sizeof(unsigned) ); + cudaMemcpyToSymbol(MY_CONST(virial) ,&sdata->pair.virial.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(eng_vdwl) ,&sdata->pair.eng_vdwl.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(periodicity) , sdata->domain.periodicity , sizeof(int)*3 ); + cudaMemcpyToSymbol(MY_CONST(collect_forces_later), &sdata->pair.collect_forces_later , sizeof(int) ); + cudaMemcpyToSymbol("params_sw", params_host , sizeof(ParamSW_Float)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("elem2param",elem2param_host , sizeof(int)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("map",map_host , sizeof(int)*cuda_ntypes ); + cudaMemcpyToSymbol("nelements",&nelements_h, sizeof(int)); +} + +void Cuda_PairSWCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom) +{ + static int glob_ij_size=0; + static F_FLOAT4* glob_r_ij=NULL; + static int* glob_numneigh_red=NULL; + static int* glob_neighbors_red=NULL; + static int* glob_neightype_red=NULL; + + if(glob_ij_size < sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT)) + { + glob_ij_size = sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT); + cudaFree(glob_r_ij); + cudaFree(glob_numneigh_red); + cudaFree(glob_neighbors_red); + cudaFree(glob_neightype_red); + cudaMalloc(&glob_r_ij,glob_ij_size*4); + cudaMalloc(&glob_numneigh_red,sdata->atom.nall*sizeof(int)); + cudaMalloc(&glob_neighbors_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMalloc(&glob_neightype_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMemcpyToSymbol("_glob_numneigh_red", &glob_numneigh_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neighbors_red", &glob_neighbors_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neightype_red", &glob_neightype_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_r_ij", &glob_r_ij , sizeof(F_FLOAT4*) ); + } + dim3 grid,threads; + int sharedperproc; + + Cuda_Pair_PreKernel_AllStyles(sdata, sneighlist, eflag, vflag, grid, threads, sharedperproc,false,64); + cudaStream_t* streams = (cudaStream_t*) CudaWrapper_returnStreams(); + + + + dim3 grid2; + if(sdata->atom.nall<=256*64000){ + grid2.x = (sdata->atom.nall+255)/256; + grid2.y = 1; + } else { + grid2.x = (sdata->atom.nall+256*128-1)/(256*128); + grid2.y = 128; + } + grid2.z = 1; + dim3 threads2; + threads2.x = 256; + threads2.y = 1; + threads2.z = 1; + + timespec time1,time2; + + //pre-calculate all neighbordistances and zeta_ij + clock_gettime(CLOCK_REALTIME,&time1); + Pair_SW_Kernel_TpA_RIJ<<>>(); + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test1+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + clock_gettime(CLOCK_REALTIME,&time1); + + //actual force calculation + unsigned int sharedsize=(sharedperproc*sizeof(ENERGY_FLOAT)+4*sizeof(F_FLOAT))*threads.x; //extra 4 floats per thread used to reduce register pressure + if(eflag) + { + if(vflag) + Pair_SW_Kernel_TpA<1,1><<>> + (eflag_atom,vflag_atom); + else + Pair_SW_Kernel_TpA<1,0><<>> + (eflag_atom,vflag_atom); + } + else + { + if(vflag) + Pair_SW_Kernel_TpA<0,1><<>> + (eflag_atom,vflag_atom); + else + Pair_SW_Kernel_TpA<0,0><<>> + (eflag_atom,vflag_atom); + } + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test2+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + + Cuda_Pair_PostKernel_AllStyles(sdata, grid, sharedperproc, eflag, vflag); +} + diff --git a/lib/cuda/pair_sw_cuda_cu.h b/lib/cuda/pair_sw_cuda_cu.h new file mode 100644 index 0000000000..24e92689ff --- /dev/null +++ b/lib/cuda/pair_sw_cuda_cu.h @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include "cuda_shared.h" + + struct ParamSW_Float { + F_FLOAT epsilon,sigma; + F_FLOAT littlea,lambda,gamma,costheta; + F_FLOAT biga,bigb; + F_FLOAT powerp,powerq; + F_FLOAT tol; + F_FLOAT cut,cutsq; + F_FLOAT sigma_gamma,lambda_epsilon,lambda_epsilon2; + F_FLOAT c1,c2,c3,c4,c5,c6; + int ielement,jelement,kelement; + }; + +extern "C" void Cuda_PairSWCuda_Init(cuda_shared_data* sdata,ParamSW_Float* params_host,void* map_host, void* elem2param_host,int nelements_h); +extern "C" void Cuda_PairSWCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom); diff --git a/lib/cuda/pair_sw_cuda_kernel_nc.cu b/lib/cuda/pair_sw_cuda_kernel_nc.cu new file mode 100644 index 0000000000..8072822559 --- /dev/null +++ b/lib/cuda/pair_sw_cuda_kernel_nc.cu @@ -0,0 +1,449 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ +#define Pi F_F(3.1415926535897932384626433832795) +#define PI Pi +#define PI2 F_F(0.5)*Pi +#define PI4 F_F(0.25)*Pi + + + +__device__ void twobody(int iparam, F_FLOAT rsq, F_FLOAT &fforce, + int eflag, ENERGY_FLOAT &eng) +{ + F_FLOAT r,rp,rq,rainv,expsrainv; + + r = sqrt(rsq); + rp = pow(r,-params_sw[iparam].powerp); + rq = pow(r,-params_sw[iparam].powerq); + rainv = 1.0 / (r - params_sw[iparam].cut); + expsrainv = exp(params_sw[iparam].sigma * rainv); + fforce = (params_sw[iparam].c1*rp - params_sw[iparam].c2*rq + + (params_sw[iparam].c3*rp -params_sw[iparam].c4*rq) * rainv*rainv*r) * expsrainv / rsq; + if (eflag) eng += (params_sw[iparam].c5*rp - params_sw[iparam].c6*rq) * expsrainv; +} + +__device__ void threebody(int paramij, int paramik, int paramijk, + F_FLOAT4& delr1, + F_FLOAT4& delr2, + F_FLOAT3& fj, F_FLOAT3& fk, int eflag,ENERGY_FLOAT &eng) +{ + F_FLOAT r1,rinvsq1,rainv1,gsrainv1,gsrainvsq1,expgsrainv1; + F_FLOAT r2,rinvsq2,rainv2,gsrainv2,gsrainvsq2,expgsrainv2; + F_FLOAT rinv12,cs,delcs,delcssq,facexp,facrad,frad1,frad2; + F_FLOAT facang,facang12,csfacang,csfac1,csfac2; + + r1 = sqrt(delr1.w); + rinvsq1 = F_F(1.0)/delr1.w; + rainv1 = F_F(1.0)/(r1 - params_sw[paramij].cut); + gsrainv1 = params_sw[paramij].sigma_gamma * rainv1; + gsrainvsq1 = gsrainv1*rainv1/r1; + expgsrainv1 = exp(gsrainv1); + + r2 = sqrt(delr2.w); + rinvsq2 = F_F(1.0)/delr2.w; + rainv2 = F_F(1.0)/(r2 - params_sw[paramik].cut); + gsrainv2 = params_sw[paramik].sigma_gamma * rainv2; + gsrainvsq2 = gsrainv2*rainv2/r2; + expgsrainv2 = exp(gsrainv2); + + rinv12 = F_F(1.0)/(r1*r2); + cs = (delr1.x*delr2.x + delr1.y*delr2.y + delr1.z*delr2.z) * rinv12; + delcs = cs - params_sw[paramijk].costheta; + delcssq = delcs*delcs; + + facexp = expgsrainv1*expgsrainv2; + + // facrad = sqrt(paramij->lambda_epsilon*paramik->lambda_epsilon) * + // facexp*delcssq; + + facrad = params_sw[paramijk].lambda_epsilon * facexp*delcssq; + frad1 = facrad*gsrainvsq1; + frad2 = facrad*gsrainvsq2; + facang = params_sw[paramijk].lambda_epsilon2 * facexp*delcs; + facang12 = rinv12*facang; + csfacang = cs*facang; + csfac1 = rinvsq1*csfacang; + + fj.x = delr1.x*(frad1+csfac1)-delr2.x*facang12; + fj.y = delr1.y*(frad1+csfac1)-delr2.y*facang12; + fj.z = delr1.z*(frad1+csfac1)-delr2.z*facang12; + + csfac2 = rinvsq2*csfacang; + + fk.x = delr2.x*(frad2+csfac2)-delr1.x*facang12; + fk.y = delr2.y*(frad2+csfac2)-delr1.y*facang12; + fk.z = delr2.z*(frad2+csfac2)-delr1.z*facang12; + + if (eflag) eng+= F_F(2.0)*facrad; +} + +__device__ void threebody_fj(int paramij, int paramik, int paramijk, + F_FLOAT4& delr1, + F_FLOAT4& delr2, + F_FLOAT3& fj) +{ + F_FLOAT r1,rinvsq1,rainv1,gsrainv1,gsrainvsq1,expgsrainv1; + F_FLOAT r2,rainv2,gsrainv2,expgsrainv2; + F_FLOAT rinv12,cs,delcs,delcssq,facexp,facrad,frad1; + F_FLOAT facang,facang12,csfacang,csfac1; + + r1 = sqrt(delr1.w); + rinvsq1 = F_F(1.0)/delr1.w; + rainv1 = F_F(1.0)/(r1 - params_sw[paramij].cut); + gsrainv1 = params_sw[paramij].sigma_gamma * rainv1; + gsrainvsq1 = gsrainv1*rainv1/r1; + expgsrainv1 = exp(gsrainv1); + + r2 = sqrt(delr2.w); + rainv2 = F_F(1.0)/(r2 - params_sw[paramik].cut); + gsrainv2 = params_sw[paramik].sigma_gamma * rainv2; + expgsrainv2 = exp(gsrainv2); + + rinv12 = F_F(1.0)/(r1*r2); + cs = (delr1.x*delr2.x + delr1.y*delr2.y + delr1.z*delr2.z) * rinv12; + delcs = cs - params_sw[paramijk].costheta; + delcssq = delcs*delcs; + + facexp = expgsrainv1*expgsrainv2; + + // facrad = sqrt(paramij->lambda_epsilon*paramik->lambda_epsilon) * + // facexp*delcssq; + + facrad = params_sw[paramijk].lambda_epsilon * facexp*delcssq; + frad1 = facrad*gsrainvsq1; + facang = params_sw[paramijk].lambda_epsilon2 * facexp*delcs; + facang12 = rinv12*facang; + csfacang = cs*facang; + csfac1 = rinvsq1*csfacang; + + fj.x = delr1.x*(frad1+csfac1)-delr2.x*facang12; + fj.y = delr1.y*(frad1+csfac1)-delr2.y*facang12; + fj.z = delr1.z*(frad1+csfac1)-delr2.z*facang12; +} + + +__global__ void Pair_SW_Kernel_TpA_RIJ()//F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + if( ii >= _nall ) return; + + X_FLOAT4 myxtype; + F_FLOAT4 delij; + F_FLOAT xtmp,ytmp,ztmp; + int itype,jnum,i,j; + int* jlist; + int neigh_red = 0; + i = ii;//_ilist[ii]; + myxtype = fetchXType(i); + + xtmp=myxtype.x; + ytmp=myxtype.y; + ztmp=myxtype.z; + itype=map[(static_cast (myxtype.w))]; + + jnum = _numneigh[i]; + jlist = &_neighbors[i]; + + __syncthreads(); + for (int jj = 0; jj < jnum; jj++) + { + if(jj (myxtype.w))]; + int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + delij.w = vec3_dot(delij,delij); + if (delij.w < params_sw[iparam_ij].cutsq) + { + _glob_neighbors_red[i+neigh_red*_nall]=j; + _glob_neightype_red[i+neigh_red*_nall]=jtype; + _glob_r_ij[i+neigh_red*_nall]=delij; + neigh_red++; + } + } + } + _glob_numneigh_red[i]=neigh_red; +} + + + template + __global__ void Pair_SW_Kernel_TpA(int eflag_atom,int vflag_atom)//,F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + ENERGY_FLOAT evdwl = ENERGY_F(0.0); + + ENERGY_FLOAT* sharedE = &sharedmem[threadIdx.x]; + ENERGY_FLOAT* sharedV = &sharedmem[threadIdx.x]; + + F_FLOAT* shared_F_F = (F_FLOAT*) sharedmem; + if((eflag||eflag_atom)&&(vflagm||vflag_atom)) shared_F_F = (F_FLOAT*) &sharedmem[7*blockDim.x]; + else + if(eflag) shared_F_F = (F_FLOAT*) &sharedmem[blockDim.x]; + else + if(vflagm) shared_F_F = (F_FLOAT*) &sharedmem[6*blockDim.x]; + shared_F_F+=threadIdx.x; + + if(eflag_atom||eflag) + { + sharedE[0] = ENERGY_F(0.0); + sharedV += blockDim.x; + } + + if(vflagm||vflag_atom) + { + sharedV[0*blockDim.x] = ENERGY_F(0.0); + sharedV[1*blockDim.x] = ENERGY_F(0.0); + sharedV[2*blockDim.x] = ENERGY_F(0.0); + sharedV[3*blockDim.x] = ENERGY_F(0.0); + sharedV[4*blockDim.x] = ENERGY_F(0.0); + sharedV[5*blockDim.x] = ENERGY_F(0.0); + } + + int jnum_red=0; +#define fxtmp shared_F_F[0] +#define fytmp shared_F_F[blockDim.x] +#define fztmp shared_F_F[2*blockDim.x] +//#define jnum_red (static_cast (shared_F_F[3*blockDim.x])) + + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + X_FLOAT4 myxtype_i,myxtype_j,myxtype_k; + F_FLOAT4 delij,delik,deljk; + F_FLOAT fpair; + + int itype,i,j; + int* jlist_red; + + if(ii < _inum) + { + i = _ilist[ii]; + + if(vflagm) + myxtype_i=fetchXType(i); + //itype=map[(static_cast (myxtype_i.w))]; + itype=map[_type[i]]; + + + fxtmp = F_F(0.0); + fytmp = F_F(0.0); + fztmp = F_F(0.0); + + + //shared_F_F[3*blockDim.x] = _glob_numneigh_red[i]; + jnum_red = _glob_numneigh_red[i]; + jlist_red = &_glob_neighbors_red[i]; + } + __syncthreads(); +#pragma unroll 1 + for (int jj = 0; jj < jnum_red; jj++) + { + if(i < _nlocal) + { + fpair=F_F(0.0); + j = jlist_red[jj*_nall]; + j &= NEIGHMASK; + + if(vflagm) + myxtype_j = fetchXType(j); + + int jtype = _glob_neightype_red[i+jj*_nall]; + delij = _glob_r_ij[i+jj*_nall]; + + volatile int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + volatile int iparam_ji = elem2param[(jtype*nelements+itype)*nelements+itype]; + + if (delij.w(); +#undef fxtmp +#undef fytmp +#undef fztmp +//#undef jnum_red +} diff --git a/lib/cuda/pair_tersoff_cuda.cu b/lib/cuda/pair_tersoff_cuda.cu new file mode 100644 index 0000000000..abbf39ecf0 --- /dev/null +++ b/lib/cuda/pair_tersoff_cuda.cu @@ -0,0 +1,155 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include + + +#include "pair_tersoff_cuda_cu.h" +__device__ __constant__ Param_Float params[MANYBODY_NPAIR*MANYBODY_NPAIR*MANYBODY_NPAIR]; +__device__ __constant__ F_FLOAT* _glob_zeta_ij; //zeta_ij +__device__ __constant__ F_FLOAT4* _glob_r_ij; //r_ij (x,y,z,r^2) for pairs within force cutoff +__device__ __constant__ bool _zbl; //is tersoff zbl? + + +#include "pair_tersoff_cuda_kernel_nc.cu" + +#include + + +void Cuda_PairTersoffCuda_Init(cuda_shared_data* sdata,Param_Float* params_host,void* map_host, void* elem2param_host,int nelements_h,bool zbl) +{ + unsigned cuda_ntypes = sdata->atom.ntypes + 1; + X_FLOAT box_size[3] = + { + sdata->domain.subhi[0] - sdata->domain.sublo[0], + sdata->domain.subhi[1] - sdata->domain.sublo[1], + sdata->domain.subhi[2] - sdata->domain.sublo[2] + }; + + cudaMemcpyToSymbol(MY_CONST(box_size) , box_size , sizeof(X_FLOAT)*3); + cudaMemcpyToSymbol(MY_CONST(cuda_ntypes) ,&cuda_ntypes , sizeof(unsigned) ); + cudaMemcpyToSymbol(MY_CONST(virial) ,&sdata->pair.virial.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(eng_vdwl) ,&sdata->pair.eng_vdwl.dev_data , sizeof(ENERGY_FLOAT*) ); + cudaMemcpyToSymbol(MY_CONST(periodicity) , sdata->domain.periodicity , sizeof(int)*3 ); + cudaMemcpyToSymbol(MY_CONST(collect_forces_later), &sdata->pair.collect_forces_later , sizeof(int) ); + cudaMemcpyToSymbol("params", params_host , sizeof(Param_Float)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("elem2param",elem2param_host , sizeof(int)*nelements_h*nelements_h*nelements_h ); + cudaMemcpyToSymbol("map",map_host , sizeof(int)*cuda_ntypes ); + cudaMemcpyToSymbol("nelements",&nelements_h, sizeof(int)); + cudaMemcpyToSymbol("_zbl",&zbl,sizeof(bool)); + +} + +void Cuda_PairTersoffCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom) +{ + static F_FLOAT* glob_zeta_ij=NULL; + static int glob_zeta_ij_size=0; + static F_FLOAT4* glob_r_ij=NULL; + static int* glob_numneigh_red=NULL; + static int* glob_neighbors_red=NULL; + static int* glob_neightype_red=NULL; + + if(glob_zeta_ij_size < sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT)) + { + glob_zeta_ij_size = sdata->atom.nall*sneighlist->maxneighbors*sizeof(F_FLOAT); + cudaFree(glob_zeta_ij); + cudaFree(glob_r_ij); + cudaFree(glob_numneigh_red); + cudaFree(glob_neighbors_red); + cudaFree(glob_neightype_red); + cudaMalloc(&glob_zeta_ij,glob_zeta_ij_size); + cudaMalloc(&glob_r_ij,glob_zeta_ij_size*4); + cudaMalloc(&glob_numneigh_red,sdata->atom.nall*sizeof(int)); + cudaMalloc(&glob_neighbors_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMalloc(&glob_neightype_red,sdata->atom.nall*sneighlist->maxneighbors*sizeof(int)); + cudaMemcpyToSymbol("_glob_numneigh_red", &glob_numneigh_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neighbors_red", &glob_neighbors_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_neightype_red", &glob_neightype_red , sizeof(int*) ); + cudaMemcpyToSymbol("_glob_r_ij", &glob_r_ij , sizeof(F_FLOAT4*) ); + cudaMemcpyToSymbol("_glob_zeta_ij", &glob_zeta_ij , sizeof(F_FLOAT*) ); + } + dim3 grid,threads; + int sharedperproc; + + Cuda_Pair_PreKernel_AllStyles(sdata, sneighlist, eflag, vflag, grid, threads, sharedperproc,false,64); + cudaStream_t* streams = (cudaStream_t*) CudaWrapper_returnStreams(); + + + + dim3 grid2; + if(sdata->atom.nall<=256*64000){ + grid2.x = (sdata->atom.nall+255)/256; + grid2.y = 1; + } else { + grid2.x = (sdata->atom.nall+256*128-1)/(256*128); + grid2.y = 128; + } + grid2.z = 1; + dim3 threads2; + threads2.x = 256; + threads2.y = 1; + threads2.z = 1; + + timespec time1,time2; + + //pre-calculate all neighbordistances and zeta_ij + clock_gettime(CLOCK_REALTIME,&time1); + Pair_Tersoff_Kernel_TpA_RIJ<<>> + (); + cudaThreadSynchronize(); + Pair_Tersoff_Kernel_TpA_ZetaIJ<<>> + (); + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test1+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + clock_gettime(CLOCK_REALTIME,&time1); + + //actual force calculation + unsigned int sharedsize=(sharedperproc*sizeof(ENERGY_FLOAT)+4*sizeof(F_FLOAT))*threads.x; //extra 4 floats per thread used to reduce register pressure + if(eflag) + { + if(vflag) + Pair_Tersoff_Kernel_TpA<1,1><<>> + (eflag_atom,vflag_atom); + else + Pair_Tersoff_Kernel_TpA<1,0><<>> + (eflag_atom,vflag_atom); + } + else + { + if(vflag) + Pair_Tersoff_Kernel_TpA<0,1><<>> + (eflag_atom,vflag_atom); + else + Pair_Tersoff_Kernel_TpA<0,0><<>> + (eflag_atom,vflag_atom); + } + cudaThreadSynchronize(); + clock_gettime(CLOCK_REALTIME,&time2); + sdata->cuda_timings.test2+= + time2.tv_sec-time1.tv_sec+1.0*(time2.tv_nsec-time1.tv_nsec)/1000000000; + + Cuda_Pair_PostKernel_AllStyles(sdata, grid, sharedperproc, eflag, vflag); +} + diff --git a/lib/cuda/pair_tersoff_cuda_cu.h b/lib/cuda/pair_tersoff_cuda_cu.h new file mode 100644 index 0000000000..5276cd1c35 --- /dev/null +++ b/lib/cuda/pair_tersoff_cuda_cu.h @@ -0,0 +1,42 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#include "cuda_shared.h" + + struct Param_Float { + F_FLOAT lam1,lam2,lam3; + F_FLOAT c,d,h; + F_FLOAT gamma,powerm; + F_FLOAT powern,beta; + F_FLOAT biga,bigb,bigd,bigr; + F_FLOAT cut,cutsq; + F_FLOAT c1,c2,c3,c4; + int ielement,jelement,kelement; + int powermint; + //F_FLOAT Z_i,Z_j; + F_FLOAT ZBLcut,ZBLexpscale; + F_FLOAT a_ij,premult; + }; + +extern "C" void Cuda_PairTersoffCuda_Init(cuda_shared_data* sdata,Param_Float* params_host,void* map_host, void* elem2param_host,int nelements_h,bool zbl); +extern "C" void Cuda_PairTersoffCuda(cuda_shared_data* sdata, cuda_shared_neighlist* sneighlist, int eflag, int vflag,int eflag_atom,int vflag_atom); diff --git a/lib/cuda/pair_tersoff_cuda_kernel_nc.cu b/lib/cuda/pair_tersoff_cuda_kernel_nc.cu new file mode 100644 index 0000000000..f94f35a587 --- /dev/null +++ b/lib/cuda/pair_tersoff_cuda_kernel_nc.cu @@ -0,0 +1,1054 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ +#define Pi F_F(3.1415926535897932384626433832795) +#define PI Pi +#define PI2 F_F(0.5)*Pi +#define PI4 F_F(0.25)*Pi +template +static inline __device__ void PairVirialCompute_A_Kernel_Template() +{ + __syncthreads(); + ENERGY_FLOAT* shared=sharedmem; + + if(eflag) + { + reduceBlock(shared); + shared+=blockDim.x; + } + if(vflag) + { + reduceBlock(shared + 0 * blockDim.x); + reduceBlock(shared + 1 * blockDim.x); + reduceBlock(shared + 2 * blockDim.x); + reduceBlock(shared + 3 * blockDim.x); + reduceBlock(shared + 4 * blockDim.x); + reduceBlock(shared + 5 * blockDim.x); + } + if(threadIdx.x == 0) + { + shared=sharedmem; + ENERGY_FLOAT* buffer = (ENERGY_FLOAT*) _buffer; + if(eflag) + { + buffer[blockIdx.x * gridDim.y + blockIdx.y] = ENERGY_F(0.5)*shared[0]; + shared+=blockDim.x; buffer+=gridDim.x * gridDim.y; + } + if(vflag) + { + buffer[blockIdx.x * gridDim.y + blockIdx.y + 0 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[0 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 1 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[1 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 2 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[2 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 3 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[3 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 4 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[4 * blockDim.x]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + 5 * gridDim.x * gridDim.y] = ENERGY_F(0.5)*shared[5 * blockDim.x]; + } + } + __syncthreads(); +} + +__global__ void virial_fdotr_compute_kernel(int eflag) +{ + int i = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + ENERGY_FLOAT* sharedE = (ENERGY_FLOAT*) &sharedmem[0]; + ENERGY_FLOAT* sharedVirial = (ENERGY_FLOAT*) &sharedE[blockDim.x]; + sharedE+=threadIdx.x; + sharedVirial+=threadIdx.x; + if(i<_nlocal) + { + + F_FLOAT x = _x[i]; + F_FLOAT y = _x[i+_nmax]; + F_FLOAT z = _x[i+2*_nmax]; + F_FLOAT fx = _f[i]; + F_FLOAT fy = _f[i+_nmax]; + F_FLOAT fz = _f[i+2*_nmax]; + //if(fz*z*fz*z>1e-5) printf("V %i %i %e %e %e %e %e %e\n",i,_tag[i],x,y,z,fx,fy,fz); + sharedVirial[0] = fx*x; + sharedVirial[1*blockDim.x] = fy*y; + sharedVirial[2*blockDim.x] = fz*z; + sharedVirial[3*blockDim.x] = fy*x; + sharedVirial[4*blockDim.x] = fz*x; + sharedVirial[5*blockDim.x] = fz*y; + } else { + sharedVirial[0] = 0; + sharedVirial[1*blockDim.x] = 0; + sharedVirial[2*blockDim.x] = 0; + sharedVirial[3*blockDim.x] = 0; + sharedVirial[4*blockDim.x] = 0; + sharedVirial[5*blockDim.x] = 0; + } + sharedVirial = (ENERGY_FLOAT*) &sharedmem[0]; + sharedVirial += blockDim.x; + reduceBlockP2(sharedVirial); + reduceBlockP2(&sharedVirial[1*blockDim.x]); + reduceBlockP2(&sharedVirial[2*blockDim.x]); + reduceBlockP2(&sharedVirial[3*blockDim.x]); + reduceBlockP2(&sharedVirial[4*blockDim.x]); + reduceBlockP2(&sharedVirial[5*blockDim.x]); + if(threadIdx.x<6) + { + ENERGY_FLOAT* buffer = (ENERGY_FLOAT*) _buffer; + if(eflag) buffer = &buffer[gridDim.x*gridDim.y]; + buffer[blockIdx.x * gridDim.y + blockIdx.y + threadIdx.x * gridDim.x * gridDim.y]= sharedVirial[threadIdx.x*blockDim.x]; + } +} + +/*#define vec3_scale(K,X,Y) Y.x = K*X.x; Y.y = K*X.y; Y.z = K*X.z; +#define vec3_scaleadd(K,X,Y,Z) Z.x = K*X.x+Y.x; Z.y = K*X.y+Y.y; Z.z = K*X.z+Y.z; +#define vec3_add(X,Y,Z) Z.x = X.x+Y.x; Z.y = X.y+Y.y; Z.z = X.z+Y.z; +#define vec3_dot(X,Y) (X.x*Y.x + X.y*Y.y + X.z*Y.z)*/ + +__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT3& x, F_FLOAT3& y) { + y.x = k*x.x; y.y = k*x.y; y.z = k*x.z; +} + +__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT4& x, F_FLOAT3& y) { + y.x = k*x.x; y.y = k*x.y; y.z = k*x.z; +} + +__device__ inline void vec3_scale(F_FLOAT k, F_FLOAT4& x, F_FLOAT4& y) { + y.x = k*x.x; y.y = k*x.y; y.z = k*x.z; +} + +__device__ inline void vec3_scaleadd(F_FLOAT k, F_FLOAT3& x, F_FLOAT3& y, F_FLOAT3& z) { + z.x = k*x.x+y.x; z.y = k*x.y+y.y; z.z = k*x.z+y.z; +} + +__device__ inline void vec3_add(F_FLOAT3& x, F_FLOAT3& y, F_FLOAT3& z) { + z.x = x.x+y.x; z.y = x.y+y.y; z.z = x.z+y.z; +} + +__device__ inline F_FLOAT vec3_dot(F_FLOAT3 x, F_FLOAT3 y) { + return x.x*y.x + x.y*y.y + x.z*y.z; +} + +__device__ inline F_FLOAT vec3_dot(F_FLOAT4 x, F_FLOAT4 y) { + return x.x*y.x + x.y*y.y + x.z*y.z; +} + +/* ---------------------------------------------------------------------- + Fermi-like smoothing function +------------------------------------------------------------------------- */ + +__device__ inline F_FLOAT F_fermi(F_FLOAT &r, int &iparam) +{ + return F_F(1.0) / (F_F(1.0) + exp(-params[iparam].ZBLexpscale*(r-params[iparam].ZBLcut))); +} + +/* ---------------------------------------------------------------------- + Fermi-like smoothing function derivative with respect to r +------------------------------------------------------------------------- */ + +__device__ inline F_FLOAT F_fermi_d(F_FLOAT &r, int &iparam) +{ + volatile const F_FLOAT tmp = exp(-params[iparam].ZBLexpscale*(r-params[iparam].ZBLcut)); + return params[iparam].ZBLexpscale*tmp / + ((F_F(1.0) +tmp)*(F_F(1.0) +tmp)); +} + +__device__ inline F_FLOAT ters_fc(F_FLOAT r, F_FLOAT ters_R, F_FLOAT ters_D) +{ + return (r < ters_R-ters_D)?F_F(1.0):((r > ters_R+ters_D)? + F_F(0.0):F_F(0.5)*(F_F(1.0) - sin(PI2*(r - ters_R)/ters_D))); +} + +__device__ inline F_FLOAT ters_fc_d(F_FLOAT r, F_FLOAT ters_R, F_FLOAT ters_D) +{ + return ((r < ters_R-ters_D)||(r > ters_R+ters_D))? + F_F(0.0):-(PI4/ters_D) * cos(PI2*(r - ters_R)/ters_D); +} + + +__device__ inline F_FLOAT ters_gijk(F_FLOAT& cos_theta, int iparam) +{ + F_FLOAT ters_c = params[iparam].c; + F_FLOAT ters_d = params[iparam].d; + + return params[iparam].gamma*(F_F(1.0) + pow(params[iparam].c/params[iparam].d,F_F(2.0)) - + pow(ters_c,F_F(2.0)) / (pow(ters_d,F_F(2.0)) + pow(params[iparam].h - cos_theta,F_F(2.0)))); +} + +__device__ F_FLOAT ters_gijk2(F_FLOAT& cos_theta, int iparam) +{ + F_FLOAT ters_c = params[iparam].c; + F_FLOAT ters_d = params[iparam].d; + + return params[iparam].gamma*(F_F(1.0) + pow(ters_c/ters_d,F_F(2.0)) - + pow(ters_c,F_F(2.0)) / (pow(ters_d,F_F(2.0)) + pow(params[iparam].h - cos_theta,F_F(2.0)))); +} + +__device__ inline F_FLOAT ters_gijk_d(F_FLOAT costheta, int iparam) +{ + F_FLOAT numerator = -F_F(2.0) * pow(params[iparam].c,F_F(2.0)) * (params[iparam].h - costheta); + F_FLOAT denominator = pow(pow(params[iparam].d,F_F(2.0)) + + pow(params[iparam].h - costheta,F_F(2.0)),F_F(2.0)); + return params[iparam].gamma*numerator/denominator; +} + +__device__ inline F_FLOAT zeta(int iparam, const F_FLOAT rsqij, const F_FLOAT rsqik, + F_FLOAT3& delij, F_FLOAT3& delik) +{ + F_FLOAT rij,rik,costheta,arg,ex_delr; + + rij = sqrt(rsqij); + rik = sqrt(rsqik); + costheta = vec3_dot(delij,delik) / (rij*rik); + + arg = (params[iparam].powermint == 3)? (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)) : params[iparam].lam3 * (rij-rik); + + if (arg > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (arg < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(arg); + + return ters_fc(rik,params[iparam].bigr,params[iparam].bigd) * ex_delr * params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c/(params[iparam].d*params[iparam].d)) - + (params[iparam].c*params[iparam].c) / ((params[iparam].d*params[iparam].d) + (params[iparam].h - costheta)*(params[iparam].h - costheta))); +} + +__device__ void repulsive(int iparam, F_FLOAT rsq, F_FLOAT &fforce, + int eflag, ENERGY_FLOAT &eng) +{ + F_FLOAT r,tmp_fc,tmp_fc_d,tmp_exp; + + F_FLOAT ters_R = params[iparam].bigr; + F_FLOAT ters_D = params[iparam].bigd; + r = sqrt(rsq); + tmp_fc = ters_fc(r,ters_R,ters_D); + tmp_fc_d = ters_fc_d(r,ters_R,ters_D); + tmp_exp = exp(-params[iparam].lam1 * r); + if(!_zbl) + { + fforce = -params[iparam].biga * tmp_exp * (tmp_fc_d - tmp_fc*params[iparam].lam1) / r; + if (eflag) eng += tmp_fc * params[iparam].biga * tmp_exp; + } + else + { + F_FLOAT const fforce_ters = params[iparam].biga * tmp_exp * (tmp_fc_d - tmp_fc*params[iparam].lam1); + ENERGY_FLOAT eng_ters = tmp_fc * params[iparam].biga * tmp_exp; + + F_FLOAT r_ov_a = r/params[iparam].a_ij; + F_FLOAT phi = F_F(0.1818)*exp(-F_F(3.2)*r_ov_a) + F_F(0.5099)*exp(-F_F(0.9423)*r_ov_a) + + F_F(0.2802)*exp(-F_F(0.4029)*r_ov_a) + F_F(0.02817)*exp(-F_F(0.2016)*r_ov_a); + F_FLOAT dphi = (F_F(1.0)/params[iparam].a_ij) * (-F_F(3.2)*F_F(0.1818)*exp(-F_F(3.2)*r_ov_a) - + F_F(0.9423)*F_F(0.5099)*exp(-F_F(0.9423)*r_ov_a) - + F_F(0.4029)*F_F(0.2802)*exp(-F_F(0.4029)*r_ov_a) - + F_F(0.2016)*F_F(0.02817)*exp(-F_F(0.2016)*r_ov_a)); + F_FLOAT fforce_ZBL = params[iparam].premult/(-r*r)* phi + params[iparam].premult/r*dphi; + ENERGY_FLOAT eng_ZBL = params[iparam].premult*(F_F(1.0)/r)*phi; + + fforce = -(-F_fermi_d(r,iparam) * (eng_ZBL - eng_ters) + fforce_ZBL + F_fermi(r,iparam)*(fforce_ters-fforce_ZBL))/r; + if(eflag) + eng += eng_ZBL + F_fermi(r,iparam)*(eng_ters-eng_ZBL); + } + + +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_fa(F_FLOAT r, int iparam, F_FLOAT ters_R, F_FLOAT ters_D) +{ + if (r > ters_R + ters_D) return F_F(0.0); + if(_zbl) + return -params[iparam].bigb * exp(-params[iparam].lam2 * r) * ters_fc(r,ters_R,ters_D) * F_fermi(r,iparam); + else + return -params[iparam].bigb * exp(-params[iparam].lam2 * r) * ters_fc(r,ters_R,ters_D); +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_fa_d(F_FLOAT r, int iparam, F_FLOAT ters_R, F_FLOAT ters_D) +{ + if (r > ters_R + ters_D) return F_F(0.0); + if(_zbl) + return params[iparam].bigb * exp(-params[iparam].lam2 * r) * + ((params[iparam].lam2 * ters_fc(r,ters_R,ters_D) - ters_fc_d(r,ters_R,ters_D))*F_fermi(r,iparam) + -ters_fc(r,ters_R,ters_D)*F_fermi_d(r,iparam)); + else + return params[iparam].bigb * exp(-params[iparam].lam2 * r) * + (params[iparam].lam2 * ters_fc(r,ters_R,ters_D) - ters_fc_d(r,ters_R,ters_D)); +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_bij(F_FLOAT zeta, int iparam) +{ + F_FLOAT tmp = params[iparam].beta * zeta; + if (tmp > params[iparam].c1) return F_F(1.0)/sqrt(tmp); + if (tmp > params[iparam].c2) + return (F_F(1.0) - pow(tmp,-params[iparam].powern) / (F_F(2.0)*params[iparam].powern))/sqrt(tmp); + if (tmp < params[iparam].c4) return F_F(1.0); + if (tmp < params[iparam].c3) + return F_F(1.0) - pow(tmp,params[iparam].powern)/(F_F(2.0)*params[iparam].powern); + return pow(F_F(1.0) + pow(tmp,params[iparam].powern), -F_F(1.0)/(F_F(2.0)*params[iparam].powern)); +} + +/* ---------------------------------------------------------------------- */ + +__device__ inline F_FLOAT ters_bij_d(F_FLOAT zeta, int iparam) +{ + F_FLOAT tmp = params[iparam].beta * zeta; + if (tmp > params[iparam].c1) return params[iparam].beta * -F_F(0.5)*pow(tmp,-F_F(1.5)); + if (tmp > params[iparam].c2) + return params[iparam].beta * (-F_F(0.5)*pow(tmp,-F_F(1.5)) * + (F_F(1.0) - F_F(0.5)*(F_F(1.0) + F_F(1.0)/(F_F(2.0)*params[iparam].powern)) * + pow(tmp,-params[iparam].powern))); + if (tmp < params[iparam].c4) return F_F(0.0); + if (tmp < params[iparam].c3) + return -F_F(0.5)*params[iparam].beta * pow(tmp,params[iparam].powern-F_F(1.0)); + + F_FLOAT tmp_n = pow(tmp,params[iparam].powern); + return -F_F(0.5) * pow(F_F(1.0)+tmp_n, -F_F(1.0)-(F_F(1.0)/(F_F(2.0)*params[iparam].powern)))*tmp_n / zeta; +} + +__device__ void force_zeta(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij, + F_FLOAT &fforce, F_FLOAT &prefactor, + int eflag, F_FLOAT &eng) +{ + F_FLOAT r,fa,fa_d,bij; + F_FLOAT ters_R = params[iparam].bigr; + F_FLOAT ters_D = params[iparam].bigd; + r = sqrt(rsq); + fa = ters_fa(r,iparam,ters_R,ters_D); + fa_d = ters_fa_d(r,iparam,ters_R,ters_D); + bij = ters_bij(zeta_ij,iparam); + fforce = F_F(0.5)*bij*fa_d / r; + prefactor = -F_F(0.5)*fa * ters_bij_d(zeta_ij,iparam); + if (eflag) eng += bij*fa; +} + +__device__ void force_zeta_prefactor_force(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij, + F_FLOAT &fforce, F_FLOAT &prefactor) +{ + F_FLOAT r,fa,fa_d,bij; + F_FLOAT ters_R = params[iparam].bigr; + F_FLOAT ters_D = params[iparam].bigd; + r = sqrt(rsq); + fa = ters_fa(r,iparam,ters_R,ters_D); + fa_d = ters_fa_d(r,iparam,ters_R,ters_D); + bij = ters_bij(zeta_ij,iparam); + fforce = F_F(0.5)*bij*fa_d / r; + prefactor = -F_F(0.5)*fa * ters_bij_d(zeta_ij,iparam); +} + +__device__ void force_zeta_prefactor(int iparam, F_FLOAT rsq, F_FLOAT zeta_ij, + F_FLOAT &prefactor) +{ + F_FLOAT r,fa; + r = sqrt(rsq); + fa = ters_fa(r,iparam,params[iparam].bigr,params[iparam].bigd); + prefactor = -F_F(0.5)*fa*ters_bij_d(zeta_ij,iparam); +} + + +__device__ void costheta_d(F_FLOAT3& rij_hat, F_FLOAT& rij, + F_FLOAT3& rik_hat, F_FLOAT& rik, + F_FLOAT3& dri, F_FLOAT3& drj, F_FLOAT3& drk) +{ + // first element is derivative wrt Ri, second wrt Rj, third wrt Rk + + F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + + vec3_scaleadd(-cos_theta,rij_hat,rik_hat,drj); + vec3_scale(F_F(1.0)/rij,drj,drj); + vec3_scaleadd(-cos_theta,rik_hat,rij_hat,drk); + vec3_scale(F_F(1.0)/rik,drk,drk); + vec3_add(drj,drk,dri); + vec3_scale(-F_F(1.0),dri,dri); +} + +__device__ void ters_zetaterm_d(F_FLOAT prefactor, + F_FLOAT3& rij_hat, F_FLOAT rij, + F_FLOAT3& rik_hat, F_FLOAT rik, + F_FLOAT3& dri, F_FLOAT3& drj, F_FLOAT3& drk, + int iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + F_FLOAT3 dcosdri,dcosdrj,dcosdrk; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + costheta_d(rij_hat,rij,rik_hat,rik,dcosdri,dcosdrj,dcosdrk); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri + // dri = -dfc*gijk*ex_delr*rik_hat; + // dri += fc*gijk_d*ex_delr*dcosdri; + // dri += fc*gijk*ex_delr_d*(rik_hat - rij_hat); + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd); + + + vec3_scale(-dfc*gijk*ex_delr,rik_hat,dri); + vec3_scaleadd(fc*gijk_d*ex_delr,dcosdri,dri,dri); + vec3_scaleadd(fc*gijk*ex_delr_d,rik_hat,dri,dri); + vec3_scaleadd(-fc*gijk*ex_delr_d,rij_hat,dri,dri); + vec3_scale(prefactor,dri,dri); + // compute the derivative wrt Rj + // drj = fc*gijk_d*ex_delr*dcosdrj; + // drj += fc*gijk*ex_delr_d*rij_hat; + + vec3_scale(fc*gijk_d*ex_delr,dcosdrj,drj); + vec3_scaleadd(fc*gijk*ex_delr_d,rij_hat,drj,drj); + vec3_scale(prefactor,drj,drj); + + // compute the derivative wrt Rk + // drk = dfc*gijk*ex_delr*rik_hat; + // drk += fc*gijk_d*ex_delr*dcosdrk; + // drk += -fc*gijk*ex_delr_d*rik_hat; + + vec3_scale(dfc*gijk*ex_delr,rik_hat,drk); + vec3_scaleadd(fc*gijk_d*ex_delr,dcosdrk,drk,drk); + vec3_scaleadd(-fc*gijk*ex_delr_d,rik_hat,drk,drk); + vec3_scale(prefactor,drk,drk); +} + +__device__ void ters_zetaterm_d_fi(F_FLOAT &prefactor, + F_FLOAT3& rij_hat, F_FLOAT &rij, + F_FLOAT3& rik_hat, F_FLOAT &rik, + F_FLOAT3& dri, int &iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + //costheta_d(rij_hat,rij,rik_hat,rik,dcosdri,dcosdrj,dcosdrk); + + + F_FLOAT3 dcosdri; + vec3_scaleadd(-cos_theta,rij_hat,rik_hat,dri); + vec3_scale(F_F(1.0)/rij,dri,dri); + vec3_scaleadd(-cos_theta,rik_hat,rij_hat,dcosdri); + vec3_scale(F_F(1.0)/rik,dcosdri,dcosdri); + vec3_add(dri,dcosdri,dcosdri); + vec3_scale(-F_F(1.0),dcosdri,dcosdri); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri +// + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd); + + vec3_scale(-dfc*gijk*ex_delr,rik_hat,dri); + vec3_scaleadd(fc*gijk_d*ex_delr,dcosdri,dri,dri); + vec3_scaleadd(fc*gijk*ex_delr_d,rik_hat,dri,dri); + vec3_scaleadd(-fc*gijk*ex_delr_d,rij_hat,dri,dri); + vec3_scale(prefactor,dri,dri); + +} + +__device__ void ters_zetaterm_d_fj(F_FLOAT &prefactor, + F_FLOAT3& rij_hat, F_FLOAT &rij, + F_FLOAT3& rik_hat, F_FLOAT &rik, + F_FLOAT3& drj, int &iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + vec3_scaleadd(-cos_theta,rij_hat,rik_hat,drj); + vec3_scale(F_F(1.0)/rij,drj,drj); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri + + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + + vec3_scale(fc*gijk_d*ex_delr,drj,drj); + vec3_scaleadd(fc*gijk*ex_delr_d,rij_hat,drj,drj); + vec3_scale(prefactor,drj,drj); +} + +__device__ void ters_zetaterm_d_fk(F_FLOAT &prefactor, + F_FLOAT3& rij_hat, F_FLOAT &rij, + F_FLOAT3& rik_hat, F_FLOAT &rik, + F_FLOAT3& drk, int &iparam) +{ + F_FLOAT ex_delr,ex_delr_d,tmp; + + if (params[iparam].powermint == 3) tmp = (params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)*params[iparam].lam3 * (rij-rik)); + else tmp = params[iparam].lam3 * (rij-rik); + + if (tmp > F_F(69.0776)) ex_delr = F_F(1.e30); + else if (tmp < -F_F(69.0776)) ex_delr = F_F(0.0); + else ex_delr = exp(tmp); + + if (params[iparam].powermint == 3) + ex_delr_d = F_F(3.0)*(params[iparam].lam3*params[iparam].lam3*params[iparam].lam3) * (rij-rik)*(rij-rik)*ex_delr; + else ex_delr_d = params[iparam].lam3 * ex_delr; + + const F_FLOAT cos_theta = vec3_dot(rij_hat,rik_hat); + vec3_scaleadd(-cos_theta,rik_hat,rij_hat,drk); + vec3_scale(F_F(1.0)/rik,drk,drk); + + const F_FLOAT gijk = params[iparam].gamma*(F_F(1.0) + (params[iparam].c*params[iparam].c)/(params[iparam].d*params[iparam].d) - + (params[iparam].c*params[iparam].c) / (params[iparam].d*params[iparam].d + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta))); + const F_FLOAT numerator = -F_F(2.0) * params[iparam].c*params[iparam].c * (params[iparam].h - cos_theta); + const F_FLOAT denominator = (params[iparam].d*params[iparam].d) + + (params[iparam].h - cos_theta)*(params[iparam].h - cos_theta); + const F_FLOAT gijk_d = params[iparam].gamma*numerator/(denominator*denominator); // compute the derivative wrt Ri + + const F_FLOAT fc = ters_fc(rik,params[iparam].bigr,params[iparam].bigd); + const F_FLOAT dfc = ters_fc_d(rik,params[iparam].bigr,params[iparam].bigd); + + vec3_scale(fc*gijk_d*ex_delr,drk,drk); + vec3_scaleadd(dfc*gijk*ex_delr,rik_hat,drk,drk); + vec3_scaleadd(-fc*gijk*ex_delr_d,rik_hat,drk,drk); + vec3_scale(prefactor,drk,drk); +} + +__device__ void attractive(int iparam, F_FLOAT prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& fi, F_FLOAT3& fj, F_FLOAT3& fk) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d(prefactor,rij_hat,rij,rik_hat,rik,fi,fj,fk,iparam); +} + +__device__ void attractive_fi(int& iparam, F_FLOAT& prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& f) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d_fi(prefactor,rij_hat,rij,rik_hat,rik,f,iparam); +} + +__device__ void attractive_fj(int iparam, F_FLOAT prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& f) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d_fj(prefactor,rij_hat,rij,rik_hat,rik,f,iparam); +} + +__device__ void attractive_fk(int iparam, F_FLOAT prefactor, + F_FLOAT4& delij, + F_FLOAT4& delik, + F_FLOAT3& f) +{ + F_FLOAT3 rij_hat,rik_hat; + F_FLOAT rij,rijinv,rik,rikinv; + + rij = sqrt(delij.w); + rijinv = F_F(1.0)/rij; + vec3_scale(rijinv,delij,rij_hat); + + rik = sqrt(delik.w); + rikinv = F_F(1.0)/rik; + vec3_scale(rikinv,delik,rik_hat); + + ters_zetaterm_d_fk(prefactor,rij_hat,rij,rik_hat,rik,f,iparam); +} + +__global__ void Pair_Tersoff_Kernel_TpA_RIJ()//F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + if( ii >= _nall ) return; + + X_FLOAT4 myxtype; + F_FLOAT4 delij; + F_FLOAT xtmp,ytmp,ztmp; + int itype,jnum,i,j; + int* jlist; + int neigh_red = 0; + i = ii;//_ilist[ii]; + myxtype = fetchXType(i); + + xtmp=myxtype.x; + ytmp=myxtype.y; + ztmp=myxtype.z; + itype=map[(static_cast (myxtype.w))]; + + jnum = _numneigh[i]; + jlist = &_neighbors[i]; + + __syncthreads(); + for (int jj = 0; jj < jnum; jj++) + { + if(jj (myxtype.w))]; + int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + delij.w = vec3_dot(delij,delij); + if (delij.w < params[iparam_ij].cutsq) + { + _glob_neighbors_red[i+neigh_red*_nall]=j; + _glob_neightype_red[i+neigh_red*_nall]=jtype; + _glob_r_ij[i+neigh_red*_nall]=delij; + neigh_red++; + } + } + } + _glob_numneigh_red[i]=neigh_red; +} + + + __global__ void Pair_Tersoff_Kernel_TpA_ZetaIJ()//F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) + { + + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + if( ii >= _nall ) return; + + + F_FLOAT4 delij; + F_FLOAT4 delik; + + int itype,jnum,i,j; + int* jlist; + i = ii; + itype=map[(static_cast (_type[i]))]; + + jnum = _glob_numneigh_red[i]; + jlist = &_glob_neighbors_red[i]; + + __syncthreads(); + for (int jj = 0; jj < jnum; jj++) + { + if(jj + __global__ void Pair_Tersoff_Kernel_TpA(int eflag_atom,int vflag_atom)//,F_FLOAT* _glob_zeta_ij,F_FLOAT4* _glob_r_ij,int* _glob_numneigh_red,int* _glob_neighbors_red,int* _glob_neightype_red) +{ + ENERGY_FLOAT evdwl = ENERGY_F(0.0); + + ENERGY_FLOAT* sharedE = &sharedmem[threadIdx.x]; + ENERGY_FLOAT* sharedV = &sharedmem[threadIdx.x]; + + F_FLOAT* shared_F_F = (F_FLOAT*) sharedmem; + if((eflag||eflag_atom)&&(vflagm||vflag_atom)) shared_F_F = (F_FLOAT*) &sharedmem[7*blockDim.x]; + else + if(eflag) shared_F_F = (F_FLOAT*) &sharedmem[blockDim.x]; + else + if(vflagm) shared_F_F = (F_FLOAT*) &sharedmem[6*blockDim.x]; + shared_F_F+=threadIdx.x; + + if(eflag_atom||eflag) + { + sharedE[0] = ENERGY_F(0.0); + sharedV += blockDim.x; + } + + if(vflagm||vflag_atom) + { + sharedV[0*blockDim.x] = ENERGY_F(0.0); + sharedV[1*blockDim.x] = ENERGY_F(0.0); + sharedV[2*blockDim.x] = ENERGY_F(0.0); + sharedV[3*blockDim.x] = ENERGY_F(0.0); + sharedV[4*blockDim.x] = ENERGY_F(0.0); + sharedV[5*blockDim.x] = ENERGY_F(0.0); + } + + int jnum_red=0; +#define fxtmp shared_F_F[0] +#define fytmp shared_F_F[blockDim.x] +#define fztmp shared_F_F[2*blockDim.x] +//#define jnum_red (static_cast (shared_F_F[3*blockDim.x])) + + int ii = (blockIdx.x*gridDim.y+blockIdx.y)*blockDim.x+threadIdx.x; + + X_FLOAT4 myxtype_i,myxtype_j,myxtype_k; + F_FLOAT4 delij,delik,deljk; + F_FLOAT fpair; + F_FLOAT prefactor_ij,prefactor_ji; + + int itype,i,j; + int* jlist_red; + + if(ii < _inum) + { + i = _ilist[ii]; + + if(vflagm) + myxtype_i=fetchXType(i); + //itype=map[(static_cast (myxtype_i.w))]; + itype=map[_type[i]]; + + + fxtmp = F_F(0.0); + fytmp = F_F(0.0); + fztmp = F_F(0.0); + + + //shared_F_F[3*blockDim.x] = _glob_numneigh_red[i]; + jnum_red = _glob_numneigh_red[i]; + jlist_red = &_glob_neighbors_red[i]; + } + __syncthreads(); + +#pragma unroll 1 + for (int jj = 0; jj < jnum_red; jj++) + { + if(i < _nlocal) + { + fpair=F_F(0.0); + j = jlist_red[jj*_nall]; + j &= NEIGHMASK; + + if(vflagm) + myxtype_j = fetchXType(j); + + int jtype = _glob_neightype_red[i+jj*_nall]; + delij = _glob_r_ij[i+jj*_nall]; + + volatile int iparam_ij = elem2param[(itype*nelements+jtype)*nelements+jtype]; + volatile int iparam_ji = elem2param[(jtype*nelements+itype)*nelements+itype]; + + if (delij.w(); +#undef fxtmp +#undef fytmp +#undef fztmp +//#undef jnum_red +} diff --git a/lib/gpu/Makefile.linux b/lib/gpu/Makefile.linux index 1777187010..c8dd8350d1 100644 --- a/lib/gpu/Makefile.linux +++ b/lib/gpu/Makefile.linux @@ -20,8 +20,10 @@ CUDA_HOME = /usr/local/cuda NVCC = nvcc +# Tesla CUDA +CUDA_ARCH = -arch=sm_21 # newer CUDA -CUDA_ARCH = -arch=sm_13 +#CUDA_ARCH = -arch=sm_13 # older CUDA #CUDA_ARCH = -arch=sm_10 -DCUDA_PRE_THREE diff --git a/src/ASPHERE/Install.sh b/src/ASPHERE/Install.sh index a494ae63d7..77a640197c 100644 --- a/src/ASPHERE/Install.sh +++ b/src/ASPHERE/Install.sh @@ -8,9 +8,13 @@ if (test $1 = 1) then cp fix_nph_asphere.cpp .. cp fix_npt_asphere.cpp .. cp fix_nve_asphere.cpp .. + cp fix_nve_line.cpp .. + cp fix_nve_tri.cpp .. cp fix_nvt_asphere.cpp .. cp pair_gayberne.cpp .. + cp pair_line_lj.cpp .. cp pair_resquared.cpp .. + cp pair_tri_lj.cpp .. cp compute_erotate_asphere.h .. cp compute_temp_asphere.h .. @@ -18,9 +22,13 @@ if (test $1 = 1) then cp fix_nph_asphere.h .. cp fix_npt_asphere.h .. cp fix_nve_asphere.h .. + cp fix_nve_line.h .. + cp fix_nve_tri.h .. cp fix_nvt_asphere.h .. cp pair_gayberne.h .. + cp pair_line_lj.h .. cp pair_resquared.h .. + cp pair_tri_lj.h .. elif (test $1 = 0) then @@ -30,9 +38,13 @@ elif (test $1 = 0) then rm -f ../fix_nph_asphere.cpp rm -f ../fix_npt_asphere.cpp rm -f ../fix_nve_asphere.cpp + rm -f ../fix_nve_line.cpp + rm -f ../fix_nve_tri.cpp rm -f ../fix_nvt_asphere.cpp rm -f ../pair_gayberne.cpp + rm -f ../pair_line_lj.cpp rm -f ../pair_resquared.cpp + rm -f ../pair_tri_lj.cpp rm -f ../compute_erotate_asphere.h rm -f ../compute_temp_asphere.h @@ -40,8 +52,12 @@ elif (test $1 = 0) then rm -f ../fix_nph_asphere.h rm -f ../fix_npt_asphere.h rm -f ../fix_nve_asphere.h + rm -f ../fix_nve_line.h + rm -f ../fix_nve_tri.h rm -f ../fix_nvt_asphere.h rm -f ../pair_gayberne.h + rm -f ../pair_line_lj.h rm -f ../pair_resquared.h + rm -f ../pair_tri_lj.h fi diff --git a/src/ASPHERE/compute_erotate_asphere.cpp b/src/ASPHERE/compute_erotate_asphere.cpp index 80c4083a9f..a18b62c1f1 100644 --- a/src/ASPHERE/compute_erotate_asphere.cpp +++ b/src/ASPHERE/compute_erotate_asphere.cpp @@ -16,6 +16,8 @@ #include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "update.h" #include "force.h" #include "memory.h" @@ -36,9 +38,12 @@ ComputeERotateAsphere(LAMMPS *lmp, int narg, char **arg) : // error check - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) - error->all(FLERR,"Compute erotate/asphere requires atom style ellipsoid"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + avec_line = (AtomVecLine *) atom->style_match("line"); + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_ellipsoid && !avec_line && !avec_tri) + error->all(FLERR,"Compute erotate/asphere requires " + "atom style ellipsoid or line or tri"); } /* ---------------------------------------------------------------------- */ @@ -49,13 +54,21 @@ void ComputeERotateAsphere::init() // no point particles allowed, spherical is OK int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; int *mask = atom->mask; int nlocal = atom->nlocal; + int flag; for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - if (ellipsoid[i] < 0) + if (mask[i] & groupbit) { + flag = 0; + if (ellipsoid && ellipsoid[i] >= 0) flag = 1; + if (line && line[i] >= 0) flag = 1; + if (tri && tri[i] >= 0) flag = 1; + if (!flag) error->one(FLERR,"Compute erotate/asphere requires extended particles"); + } pfactor = 0.5 * force->mvv2e; } @@ -66,8 +79,16 @@ double ComputeERotateAsphere::compute_scalar() { invoked_scalar = update->ntimestep; - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *ebonus; + if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; + double **omega = atom->omega; double **angmom = atom->angmom; double *rmass = atom->rmass; int *mask = atom->mask; @@ -76,6 +97,7 @@ double ComputeERotateAsphere::compute_scalar() // sum rotational energy for each particle // no point particles since divide by inertia + double length; double *shape,*quat; double wbody[3],inertia[3]; double rot[3][3]; @@ -83,28 +105,54 @@ double ComputeERotateAsphere::compute_scalar() for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { + if (ellipsoid && ellipsoid[i] >= 0) { + shape = ebonus[ellipsoid[i]].shape; + quat = ebonus[ellipsoid[i]].quat; - shape = bonus[ellipsoid[i]].shape; - quat = bonus[ellipsoid[i]].quat; + // principal moments of inertia + + inertia[0] = rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]) / 5.0; + inertia[1] = rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]) / 5.0; + inertia[2] = rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]) / 5.0; + + // wbody = angular velocity in body frame + + MathExtra::quat_to_mat(quat,rot); + MathExtra::transpose_matvec(rot,angmom[i],wbody); + wbody[0] /= inertia[0]; + wbody[1] /= inertia[1]; + wbody[2] /= inertia[2]; + + erotate += inertia[0]*wbody[0]*wbody[0] + + inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; - // principal moments of inertia + } else if (line && line[i] >= 0) { + length = lbonus[line[i]].length; - inertia[0] = rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]) / 5.0; - inertia[1] = rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]) / 5.0; - inertia[2] = rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]) / 5.0; + erotate += (omega[i][0]*omega[i][0] + omega[i][1]*omega[i][1] + + omega[i][2]*omega[i][2]) * length*length*rmass[i] / 12.0; - // wbody = angular velocity in body frame + } else if (tri && tri[i] >= 0) { - MathExtra::quat_to_mat(quat,rot); - MathExtra::transpose_matvec(rot,angmom[i],wbody); - wbody[0] /= inertia[0]; - wbody[1] /= inertia[1]; - wbody[2] /= inertia[2]; - - erotate += inertia[0]*wbody[0]*wbody[0] + - inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; + // principal moments of inertia + + inertia[0] = tbonus[tri[i]].inertia[0]; + inertia[1] = tbonus[tri[i]].inertia[1]; + inertia[2] = tbonus[tri[i]].inertia[2]; + + // wbody = angular velocity in body frame + + MathExtra::quat_to_mat(tbonus[tri[i]].quat,rot); + MathExtra::transpose_matvec(rot,angmom[i],wbody); + wbody[0] /= inertia[0]; + wbody[1] /= inertia[1]; + wbody[2] /= inertia[2]; + + erotate += inertia[0]*wbody[0]*wbody[0] + + inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; + } } - + MPI_Allreduce(&erotate,&scalar,1,MPI_DOUBLE,MPI_SUM,world); scalar *= pfactor; return scalar; diff --git a/src/ASPHERE/compute_erotate_asphere.h b/src/ASPHERE/compute_erotate_asphere.h index 0e3ae271d7..9274425795 100644 --- a/src/ASPHERE/compute_erotate_asphere.h +++ b/src/ASPHERE/compute_erotate_asphere.h @@ -32,7 +32,9 @@ class ComputeERotateAsphere : public Compute { private: double pfactor; - class AtomVecEllipsoid *avec; + class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; }; } diff --git a/src/ASPHERE/fix_nve_line.cpp b/src/ASPHERE/fix_nve_line.cpp new file mode 100644 index 0000000000..682119c6a1 --- /dev/null +++ b/src/ASPHERE/fix_nve_line.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + 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 "math.h" +#include "stdio.h" +#include "string.h" +#include "fix_nve_line.h" +#include "atom.h" +#include "atom_vec_line.h" +#include "domain.h" +#include "math_const.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define INERTIA (1.0/12.0) // moment of inertia prefactor for line segment + +/* ---------------------------------------------------------------------- */ + +FixNVELine::FixNVELine(LAMMPS *lmp, int narg, char **arg) : + FixNVE(lmp, narg, arg) +{ + if (narg != 3) error->all(FLERR,"Illegal fix nve/line command"); + + time_integrate = 1; + + MINUSPI = -MY_PI; + TWOPI = 2.0*MY_PI; + + // error checks + + avec = (AtomVecLine *) atom->style_match("line"); + if (!avec) error->all(FLERR,"Fix nve/line requires atom style line"); +} + +/* ---------------------------------------------------------------------- */ + +int FixNVELine::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE; + mask |= FINAL_INTEGRATE; + mask |= INITIAL_INTEGRATE_RESPA; + mask |= FINAL_INTEGRATE_RESPA; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixNVELine::init() +{ + int i,itype; + + if (domain->dimension != 2) + error->all(FLERR,"Fix nve/line can only be used for 2d simulations"); + + // check that all particles are line segments + // no point particles allowed + + int *line = atom->line; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (line[i] < 0) error->one(FLERR,"Fix nve/line requires line particles"); + } + + FixNVE::init(); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVELine::initial_integrate(int vflag) +{ + double dtfm,dtirotate,delx,dely,length,theta; + + AtomVecLine::Bonus *bonus = avec->bonus; + int *line = atom->line; + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + + double dtfrotate = dtf / INERTIA; + + // update v,x,omega,theta for all particles + // d_omega/dt = torque / inertia + // bound theta by -PI to PI + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + x[i][0] += dtv * v[i][0]; + x[i][1] += dtv * v[i][1]; + + length = bonus[line[i]].length; + theta = bonus[line[i]].theta; + dtirotate = dtfrotate / (length*length*rmass[i]); + omega[i][2] += dtirotate * torque[i][2]; + theta += dtv * omega[i][2]; + while (theta <= MINUSPI) theta += TWOPI; + while (theta > MY_PI) theta -= TWOPI; + bonus[line[i]].theta = theta; + } +} + +/* ---------------------------------------------------------------------- */ + +void FixNVELine::final_integrate() +{ + double dtfm,dtirotate,length; + + AtomVecLine::Bonus *bonus = avec->bonus; + int *line = atom->line; + double **v = atom->v; + double **f = atom->f; + double **omega = atom->omega; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + + double dtfrotate = dtf / INERTIA; + + // update v,omega for all particles + // d_omega/dt = torque / inertia + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + + length = bonus[line[i]].length; + dtirotate = dtfrotate / (length*length*rmass[i]); + omega[i][2] += dtirotate * torque[i][2]; + } +} diff --git a/src/ASPHERE/fix_nve_line.h b/src/ASPHERE/fix_nve_line.h new file mode 100644 index 0000000000..7d6e962044 --- /dev/null +++ b/src/ASPHERE/fix_nve_line.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(nve/line,FixNVELine) + +#else + +#ifndef LMP_FIX_NVE_LINE_H +#define LMP_FIX_NVE_LINE_H + +#include "fix_nve.h" + +namespace LAMMPS_NS { + +class FixNVELine : public FixNVE { + public: + FixNVELine(class LAMMPS *, int, char **); + ~FixNVELine() {} + int setmask(); + void init(); + void initial_integrate(int); + void final_integrate(); + + private: + double MINUSPI,TWOPI; + class AtomVecLine *avec; +}; + +} + +#endif +#endif diff --git a/src/ASPHERE/fix_nve_tri.cpp b/src/ASPHERE/fix_nve_tri.cpp new file mode 100644 index 0000000000..ca83afcdbb --- /dev/null +++ b/src/ASPHERE/fix_nve_tri.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. +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "string.h" +#include "fix_nve_tri.h" +#include "math_extra.h" +#include "atom.h" +#include "atom_vec_tri.h" +#include "domain.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +FixNVETri::FixNVETri(LAMMPS *lmp, int narg, char **arg) : + FixNVE(lmp, narg, arg) +{ + if (narg != 3) error->all(FLERR,"Illegal fix nve/tri command"); + + time_integrate = 1; + + // error checks + + avec = (AtomVecTri *) atom->style_match("tri"); + if (!avec) error->all(FLERR,"Fix nve/tri requires atom style tri"); +} + +/* ---------------------------------------------------------------------- */ + +int FixNVETri::setmask() +{ + int mask = 0; + mask |= INITIAL_INTEGRATE; + mask |= FINAL_INTEGRATE; + mask |= INITIAL_INTEGRATE_RESPA; + mask |= FINAL_INTEGRATE_RESPA; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixNVETri::init() +{ + int i,itype; + + if (domain->dimension != 3) + error->all(FLERR,"Fix nve/line can only be used for 3d simulations"); + + // check that all particles are triangles + // no point particles allowed + + int *tri = atom->tri; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + if (tri[i] < 0) error->one(FLERR,"Fix nve/tri requires tri particles"); + } + + FixNVE::init(); +} + +/* ---------------------------------------------------------------------- */ + +void FixNVETri::initial_integrate(int vflag) +{ + double dtfm; + double omega[3]; + + AtomVecTri::Bonus *bonus = avec->bonus; + int *tri = atom->tri; + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + double **angmom = atom->angmom; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // set timestep here since dt may have changed or come via rRESPA + + dtq = 0.5 * dtv; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + x[i][0] += dtv * v[i][0]; + x[i][1] += dtv * v[i][1]; + x[i][2] += dtv * v[i][2]; + + // update angular momentum by 1/2 step + + angmom[i][0] += dtf * torque[i][0]; + angmom[i][1] += dtf * torque[i][1]; + angmom[i][2] += dtf * torque[i][2]; + + // compute omega at 1/2 step from angmom at 1/2 step and current q + // update quaternion a full step via Richardson iteration + // returns new normalized quaternion + + MathExtra::mq_to_omega(angmom[i],bonus[tri[i]].quat, + bonus[tri[i]].inertia,omega); + MathExtra::richardson(bonus[tri[i]].quat,angmom[i],omega, + bonus[tri[i]].inertia,dtq); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixNVETri::final_integrate() +{ + double dtfm; + + double **v = atom->v; + double **f = atom->f; + double **angmom = atom->angmom; + double **torque = atom->torque; + double *rmass = atom->rmass; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + // update v,omega for all particles + // d_omega/dt = torque / inertia + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + dtfm = dtf / rmass[i]; + v[i][0] += dtfm * f[i][0]; + v[i][1] += dtfm * f[i][1]; + v[i][2] += dtfm * f[i][2]; + + angmom[i][0] += dtf * torque[i][0]; + angmom[i][1] += dtf * torque[i][1]; + angmom[i][2] += dtf * torque[i][2]; + } +} diff --git a/src/ASPHERE/fix_nve_tri.h b/src/ASPHERE/fix_nve_tri.h new file mode 100644 index 0000000000..e268b6b1e6 --- /dev/null +++ b/src/ASPHERE/fix_nve_tri.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(nve/tri,FixNVETri) + +#else + +#ifndef LMP_FIX_NVE_TRI_H +#define LMP_FIX_NVE_TRI_H + +#include "fix_nve.h" + +namespace LAMMPS_NS { + +class FixNVETri : public FixNVE { + public: + FixNVETri(class LAMMPS *, int, char **); + ~FixNVETri() {} + int setmask(); + void init(); + void initial_integrate(int); + void final_integrate(); + + private: + double dtq; + class AtomVecTri *avec; +}; + +} + +#endif +#endif diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp new file mode 100644 index 0000000000..ca50168be5 --- /dev/null +++ b/src/ASPHERE/pair_line_lj.cpp @@ -0,0 +1,444 @@ +/* ---------------------------------------------------------------------- + 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 "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_line_lj.h" +#include "atom.h" +#include "atom_vec_line.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +PairLineLJ::PairLineLJ(LAMMPS *lmp) : Pair(lmp) +{ + avec = (AtomVecLine *) atom->style_match("line"); + if (!avec) error->all(FLERR,"Pair line/lj requires atom style line"); + + dmax = nmax = 0; + discrete = NULL; + dnum = dfirst = NULL; + + single_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairLineLJ::~PairLineLJ() +{ + memory->sfree(discrete); + memory->destroy(dnum); + memory->destroy(dfirst); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairLineLJ::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + int ni,nj,npi,npj,ifirst,jfirst; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; + double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj; + 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; + double **torque = atom->torque; + int *line = atom->line; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // grow discrete list if necessary and initialize + + if (nall > nmax) { + memory->destroy(dnum); + memory->destroy(dfirst); + memory->create(dnum,nall,"pair:dnum"); + memory->create(dfirst,nall,"pair:dfirst"); + } + for (i = 0; i < nall; i++) dnum[i] = 0; + ndiscrete = 0; + + // 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; + + 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]) continue; + + // line/line interactions = NxN particles + + evdwl = 0.0; + if (line[i] >= 0 && line[j] >= 0) { + if (dnum[i] == 0) discretize(i,sigma[itype][itype]); + npi = dnum[i]; + ifirst = dfirst[i]; + if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); + npj = dnum[j]; + jfirst = dfirst[j]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + torque[i][2] += dxi*fi[1] - dyi*fi[0]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + torque[j][2] += dxj*fj[1] - dyj*fj[0]; + } + } + } + + // line/particle interaction = Nx1 particles + // convert line into Np particles based on sigma and line length + + } else if (line[i] >= 0) { + if (dnum[i] == 0) discretize(i,sigma[itype][itype]); + npi = dnum[i]; + ifirst = dfirst[i]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xj[0] = x[j][0]; + xj[1] = x[j][1]; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + torque[i][2] += dxi*fi[1] - dyi*fi[0]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + } + } + + // particle/line interaction = Nx1 particles + // convert line into Np particles based on sigma and line length + + } else if (line[j] >= 0) { + if (dnum[j] == 0) discretize(j,sigma[jtype][jtype]); + npj = dnum[j]; + jfirst = dfirst[j]; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + rsq = delx*delx + dely*dely; + + sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + + if (newton_pair || j < nlocal) { + f[j][0] += fj[0]; + f[j][1] += fj[1]; + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + torque[j][2] += dxj*fj[1] - dyj*fj[0]; + } + } + + // particle/particle interaction = 1x1 particles + + } else { + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = forcelj*r2inv; + + if (eflag) + evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + + 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 (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 PairLineLJ::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"); + memory->create(epsilon,n+1,n+1,"pair:epsilon"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(lj1,n+1,n+1,"pair:lj1"); + memory->create(lj2,n+1,n+1,"pair:lj2"); + memory->create(lj3,n+1,n+1,"pair:lj3"); + memory->create(lj4,n+1,n+1,"pair:lj4"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairLineLJ::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + cut_global = force->numeric(arg[0]); + + // reset cutoffs that have been explicitly set + + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i+1; j <= atom->ntypes; j++) + if (setflag[i][j]) cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairLineLJ::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 5) + error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(arg[0],atom->ntypes,ilo,ihi); + force->bounds(arg[1],atom->ntypes,jlo,jhi); + + double epsilon_one = force->numeric(arg[2]); + double sigma_one = force->numeric(arg[3]); + + double cut_one = cut_global; + if (narg == 5) cut_one = force->numeric(arg[4]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + 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 PairLineLJ::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], + sigma[i][i],sigma[j][j]); + sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + } + + lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + + epsilon[j][i] = epsilon[i][j]; + sigma[j][i] = sigma[i][j]; + lj1[j][i] = lj1[i][j]; + lj2[j][i] = lj2[i][j]; + lj3[j][i] = lj3[i][j]; + lj4[j][i] = lj4[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + discretize line segment I into N sub-segments no more than sigma in length + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +void PairLineLJ::discretize(int i, double sigma) +{ + AtomVecLine::Bonus *bonus = avec->bonus; + double length = bonus[atom->line[i]].length; + double theta = bonus[atom->line[i]].theta; + int n = static_cast (length/sigma) + 1; + dnum[i] = n; + dfirst[i] = ndiscrete; + + if (ndiscrete + n > dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + + double *x = atom->x[i]; + sigma = length/n; + double delta; + + for (int m = 0; m < n; m++) { + delta = -0.5 + (2*m+1)/(2.0*n); + discrete[ndiscrete].dx = delta*length*cos(theta); + discrete[ndiscrete].dy = delta*length*sin(theta); + discrete[ndiscrete].sigma = sigma; + ndiscrete++; + } +} diff --git a/src/ASPHERE/pair_line_lj.h b/src/ASPHERE/pair_line_lj.h new file mode 100644 index 0000000000..b30140acea --- /dev/null +++ b/src/ASPHERE/pair_line_lj.h @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------- + 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(line/lj,PairLineLJ) + +#else + +#ifndef LMP_PAIR_LINE_LJ_H +#define LMP_PAIR_LINE_LJ_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairLineLJ : public Pair { + public: + PairLineLJ(class LAMMPS *); + ~PairLineLJ(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + + protected: + double cut_global; + double **cut; + double **epsilon,**sigma; + double **lj1,**lj2,**lj3,**lj4; + class AtomVecLine *avec; + + struct Discrete { + double dx,dy; + double sigma; + }; + Discrete *discrete; // list of all discretes for all lines + int ndiscrete; // number of discretes in list + int dmax; // allocated size of discrete list + int *dnum; // number of discretes per line, 0 if uninit + int *dfirst; // index of first discrete per each line + int nmax; // allocated size of dnum,dfirst vectors + + void allocate(); + void discretize(int, double); +}; + +} + +#endif +#endif diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp new file mode 100644 index 0000000000..0ecf19aee5 --- /dev/null +++ b/src/ASPHERE/pair_tri_lj.cpp @@ -0,0 +1,637 @@ +/* ---------------------------------------------------------------------- + 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 "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_tri_lj.h" +#include "math_extra.h" +#include "atom.h" +#include "atom_vec_tri.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 20 + +/* ---------------------------------------------------------------------- */ + +PairTriLJ::PairTriLJ(LAMMPS *lmp) : Pair(lmp) +{ + avec = (AtomVecTri *) atom->style_match("tri"); + if (!avec) error->all(FLERR,"Pair tri/lj requires atom style tri"); + + dmax = nmax = 0; + discrete = NULL; + dnum = dfirst = NULL; + + single_enable = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairTriLJ::~PairTriLJ() +{ + memory->sfree(discrete); + memory->destroy(dnum); + memory->destroy(dfirst); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairTriLJ::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + int ni,nj,npi,npj,ifirst,jfirst; + double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; + double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj; + double dxi,dxj,dyi,dyj,dzi,dzj; + double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3],p[3][3]; + double dc1[3],dc2[3],dc3[3]; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + AtomVecTri::Bonus *bonus = avec->bonus; + double **x = atom->x; + double **f = atom->f; + double **torque = atom->torque; + int *tri = atom->tri; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // grow discrete list if necessary and initialize + + if (nall > nmax) { + memory->destroy(dnum); + memory->destroy(dfirst); + memory->create(dnum,nall,"pair:dnum"); + memory->create(dfirst,nall,"pair:dfirst"); + } + for (i = 0; i < nall; i++) dnum[i] = 0; + ndiscrete = 0; + + // 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; + + 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]) continue; + + // tri/tri interactions = NxN particles + // c1,c2,c3 = corner pts of triangle I or J + + evdwl = 0.0; + if (tri[i] >= 0 && tri[j] >= 0) { + if (dnum[i] == 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,dc1); + MathExtra::matvec(p,bonus[tri[i]].c2,dc2); + MathExtra::matvec(p,bonus[tri[i]].c3,dc3); + dfirst[i] = ndiscrete; + discretize(i,sigma[itype][itype],dc1,dc2,dc3); + dnum[i] = ndiscrete - dfirst[i]; + } + npi = dnum[i]; + ifirst = dfirst[i]; + + if (dnum[j] == 0) { + MathExtra::quat_to_mat(bonus[tri[j]].quat,p); + MathExtra::matvec(p,bonus[tri[j]].c1,dc1); + MathExtra::matvec(p,bonus[tri[j]].c2,dc2); + MathExtra::matvec(p,bonus[tri[j]].c3,dc3); + dfirst[j] = ndiscrete; + discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); + dnum[j] = ndiscrete - dfirst[j]; + } + npj = dnum[j]; + jfirst = dfirst[j]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + dzi = discrete[ifirst+ni].dz; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + dzj = discrete[jfirst+nj].dz; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xi[2] = x[i][2] + dzi; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + xj[2] = x[j][2] + dzj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + ti[0] = dyi*fi[2] - dzi*fi[1]; + ti[1] = dzi*fi[0] - dxi*fi[2]; + ti[2] = dxi*fi[1] - dyi*fi[0]; + torque[i][0] += ti[0]; + torque[i][1] += ti[1]; + torque[i][2] += ti[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + tj[0] = dyj*fj[2] - dzj*fj[1]; + tj[1] = dzj*fj[0] - dxj*fj[2]; + tj[2] = dxj*fj[1] - dyj*fj[0]; + torque[j][0] += tj[0]; + torque[j][1] += tj[1]; + torque[j][2] += tj[2]; + } + } + } + + // tri/particle interaction = Nx1 particles + // c1,c2,c3 = corner pts of triangle I + + } else if (tri[i] >= 0) { + + if (dnum[i] == 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,dc1); + MathExtra::matvec(p,bonus[tri[i]].c2,dc2); + MathExtra::matvec(p,bonus[tri[i]].c3,dc3); + dfirst[i] = ndiscrete; + discretize(i,sigma[itype][itype],dc1,dc2,dc3); + dnum[i] = ndiscrete - dfirst[i]; + } + npi = dnum[i]; + ifirst = dfirst[i]; + + for (ni = 0; ni < npi; ni++) { + dxi = discrete[ifirst+ni].dx; + dyi = discrete[ifirst+ni].dy; + dzi = discrete[ifirst+ni].dz; + + xi[0] = x[i][0] + dxi; + xi[1] = x[i][1] + dyi; + xi[2] = x[i][2] + dzi; + xj[0] = x[j][0]; + xj[1] = x[j][1]; + xj[2] = x[j][2]; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + ti[0] = dyi*fi[2] - dzi*fi[1]; + ti[1] = dzi*fi[0] - dxi*fi[2]; + ti[2] = dxi*fi[1] - dyi*fi[0]; + torque[i][2] += ti[0]; + torque[i][1] += ti[1]; + torque[i][2] += ti[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + } + } + + // particle/tri interaction = Nx1 particles + // c1,c2,c3 = corner pts of triangle J + + } else if (tri[j] >= 0) { + if (dnum[j] == 0) { + MathExtra::quat_to_mat(bonus[tri[j]].quat,p); + MathExtra::matvec(p,bonus[tri[j]].c1,dc1); + MathExtra::matvec(p,bonus[tri[j]].c2,dc2); + MathExtra::matvec(p,bonus[tri[j]].c3,dc3); + dfirst[j] = ndiscrete; + discretize(j,sigma[jtype][jtype],dc1,dc2,dc3); + dnum[j] = ndiscrete - dfirst[j]; + } + npj = dnum[j]; + jfirst = dfirst[j]; + + for (nj = 0; nj < npj; nj++) { + dxj = discrete[jfirst+nj].dx; + dyj = discrete[jfirst+nj].dy; + dzj = discrete[jfirst+nj].dz; + + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + xj[0] = x[j][0] + dxj; + xj[1] = x[j][1] + dyj; + xj[2] = x[j][2] + dzj; + + delx = xi[0] - xj[0]; + dely = xi[1] - xj[1]; + delz = xi[2] - xj[2]; + rsq = delx*delx + dely*dely + delz*delz; + + sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma); + sig3 = sig*sig*sig; + term2 = 24.0*epsilon[itype][jtype] * sig3*sig3; + term1 = 2.0 * term2 * sig3*sig3; + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (term1*r6inv - term2); + fpair = forcelj*r2inv; + + if (eflag) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0); + + fi[0] = delx*fpair; + fi[1] = dely*fpair; + fi[2] = delz*fpair; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + + if (newton_pair || j < nlocal) { + fj[0] = -delx*fpair; + fj[1] = -dely*fpair; + fj[2] = -delz*fpair; + f[j][0] += fj[0]; + f[j][1] += fj[1]; + f[j][2] += fj[2]; + tj[0] = dyj*fj[2] - dzj*fj[1]; + tj[1] = dzj*fj[0] - dxj*fj[2]; + tj[2] = dxj*fj[1] - dyj*fj[0]; + torque[j][0] += tj[0]; + torque[j][1] += tj[1]; + torque[j][2] += tj[2]; + } + } + + // particle/particle interaction = 1x1 particles + + } else { + r2inv = 1.0/rsq; + r6inv = r2inv*r2inv*r2inv; + forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); + fpair = forcelj*r2inv; + + if (eflag) + evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); + + 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 (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 PairTriLJ::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"); + memory->create(epsilon,n+1,n+1,"pair:epsilon"); + memory->create(sigma,n+1,n+1,"pair:sigma"); + memory->create(lj1,n+1,n+1,"pair:lj1"); + memory->create(lj2,n+1,n+1,"pair:lj2"); + memory->create(lj3,n+1,n+1,"pair:lj3"); + memory->create(lj4,n+1,n+1,"pair:lj4"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairTriLJ::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + cut_global = force->numeric(arg[0]); + + // reset cutoffs that have been explicitly set + + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i+1; j <= atom->ntypes; j++) + if (setflag[i][j]) cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairTriLJ::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 5) + error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(arg[0],atom->ntypes,ilo,ihi); + force->bounds(arg[1],atom->ntypes,jlo,jhi); + + double epsilon_one = force->numeric(arg[2]); + double sigma_one = force->numeric(arg[3]); + + double cut_one = cut_global; + if (narg == 5) cut_one = force->numeric(arg[4]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + 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 PairTriLJ::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j], + sigma[i][i],sigma[j][j]); + sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]); + cut[i][j] = mix_distance(cut[i][i],cut[j][j]); + } + + lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0); + lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0); + + epsilon[j][i] = epsilon[i][j]; + sigma[j][i] = sigma[i][j]; + lj1[j][i] = lj1[i][j]; + lj2[j][i] = lj2[i][j]; + lj3[j][i] = lj3[i][j]; + lj4[j][i] = lj4[i][j]; + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- + recursively discretize triangle I with displaced corners c1,c2,c3 + into N sub-tris no more than sigma in size + recurse by making 2 tris via bisecting longest side + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +void PairTriLJ::discretize(int i, double sigma, + double *c1, double *c2, double *c3) +{ + double c1c2[3],c2c3[3],c1c3[3]; + + double centroid[3],dc1[3],dc2[3],dc3[3]; + + centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; + centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; + centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; + + MathExtra::sub3(c1,centroid,dc1); + MathExtra::sub3(c2,centroid,dc2); + MathExtra::sub3(c3,centroid,dc3); + + double sigmasq = 0.25 * sigma*sigma; + double len1sq = MathExtra::lensq3(dc1); + double len2sq = MathExtra::lensq3(dc2); + double len3sq = MathExtra::lensq3(dc3); + + // if sigma sphere overlaps all corner points, add particle at centroid + + if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { + if (ndiscrete == dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + discrete[ndiscrete].dx = centroid[0]; + discrete[ndiscrete].dy = centroid[1]; + discrete[ndiscrete].dz = centroid[2]; + sigmasq = MAX(len1sq,len2sq); + sigmasq = MAX(sigmasq,len3sq); + discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); + ndiscrete++; + return; + } + + // else break triangle into 2 sub-triangles and recurse + + double c12[3],c23[3],c13[3],mid[3]; + + MathExtra::sub3(c2,c3,c23); + len1sq = MathExtra::lensq3(c23); + MathExtra::sub3(c1,c3,c13); + len2sq = MathExtra::lensq3(c13); + MathExtra::sub3(c1,c2,c12); + len3sq = MathExtra::lensq3(c12); + + double maxsq = MAX(len1sq,len2sq); + maxsq = MAX(maxsq,len3sq); + + if (len1sq == maxsq) { + MathExtra::add3(c2,c3,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c1,c2,mid); + discretize(i,sigma,c1,c3,mid); + } else if (len2sq == maxsq) { + MathExtra::add3(c1,c3,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c2,c1,mid); + discretize(i,sigma,c2,c3,mid); + } else { + MathExtra::add3(c1,c2,mid); + MathExtra::scale3(0.5,mid); + discretize(i,sigma,c3,c1,mid); + discretize(i,sigma,c3,c2,mid); + } +} + +/* ---------------------------------------------------------------------- + recursively discretize triangle I with displaced corners c1,c2,c3 + into N sub-tris no more than sigma in size + recurse by making 6 tris via centroid + store new discrete particles in Discrete list +------------------------------------------------------------------------- */ + +/* +void PairTriLJ::discretize(int i, double sigma, + double *c1, double *c2, double *c3) +{ + double centroid[3],dc1[3],dc2[3],dc3[3]; + + centroid[0] = (c1[0] + c2[0] + c3[0]) / 3.0; + centroid[1] = (c1[1] + c2[1] + c3[1]) / 3.0; + centroid[2] = (c1[2] + c2[2] + c3[2]) / 3.0; + + MathExtra::sub3(c1,centroid,dc1); + MathExtra::sub3(c2,centroid,dc2); + MathExtra::sub3(c3,centroid,dc3); + + double sigmasq = 0.25 * sigma*sigma; + double len1sq = MathExtra::lensq3(dc1); + double len2sq = MathExtra::lensq3(dc2); + double len3sq = MathExtra::lensq3(dc3); + + // if sigma sphere overlaps all corner points, add particle at centroid + + if (len1sq <= sigmasq && len2sq <= sigmasq & len3sq <= sigmasq) { + if (ndiscrete == dmax) { + dmax += DELTA; + discrete = (Discrete *) + memory->srealloc(discrete,dmax*sizeof(Discrete),"pair:discrete"); + } + discrete[ndiscrete].dx = centroid[0]; + discrete[ndiscrete].dy = centroid[1]; + discrete[ndiscrete].dz = centroid[2]; + sigmasq = MAX(len1sq,len2sq); + sigmasq = MAX(sigmasq,len3sq); + discrete[ndiscrete].sigma = 2.0 * sqrt(sigmasq); + ndiscrete++; + return; + } + + // else break triangle into 6 sub-triangles and recurse + + double c1c2mid[3],c2c3mid[3],c1c3mid[3]; + + MathExtra::add3(c1,c2,c1c2mid); + MathExtra::scale3(0.5,c1c2mid); + MathExtra::add3(c2,c3,c2c3mid); + MathExtra::scale3(0.5,c2c3mid); + MathExtra::add3(c1,c3,c1c3mid); + MathExtra::scale3(0.5,c1c3mid); + + discretize(i,sigma,c1,c1c2mid,centroid); + discretize(i,sigma,c1,c1c3mid,centroid); + discretize(i,sigma,c2,c2c3mid,centroid); + discretize(i,sigma,c2,c1c2mid,centroid); + discretize(i,sigma,c3,c1c3mid,centroid); + discretize(i,sigma,c3,c2c3mid,centroid); +} + +*/ diff --git a/src/ASPHERE/pair_tri_lj.h b/src/ASPHERE/pair_tri_lj.h new file mode 100644 index 0000000000..a8cf2bf721 --- /dev/null +++ b/src/ASPHERE/pair_tri_lj.h @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------- + 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(tri/lj,PairTriLJ) + +#else + +#ifndef LMP_PAIR_TRI_LJ_H +#define LMP_PAIR_TRI_LJ_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairTriLJ : public Pair { + public: + PairTriLJ(class LAMMPS *); + ~PairTriLJ(); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + + protected: + double cut_global; + double **cut; + double **epsilon,**sigma; + double **lj1,**lj2,**lj3,**lj4; + class AtomVecTri *avec; + + struct Discrete { + double dx,dy,dz; + double sigma; + }; + Discrete *discrete; // list of all discretes for all lines + int ndiscrete; // number of discretes in list + int dmax; // allocated size of discrete list + int *dnum; // number of discretes per line, 0 if uninit + int *dfirst; // index of first discrete per each line + int nmax; // allocated size of dnum,dfirst vectors + + void allocate(); + void discretize(int, double, double *, double *, double *); +}; + +} + +#endif +#endif diff --git a/src/CLASS2/angle_class2.cpp b/src/CLASS2/angle_class2.cpp index 921f2fac84..3d1847314a 100644 --- a/src/CLASS2/angle_class2.cpp +++ b/src/CLASS2/angle_class2.cpp @@ -24,10 +24,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -318,7 +320,7 @@ void AngleClass2::coeff(int narg, char **arg) // convert theta0 from degrees to radians for (int i = ilo; i <= ihi; i++) { - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; k2[i] = k2_one; k3[i] = k3_one; k4[i] = k4_one; diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp index d6e31696d7..f9c04126d8 100644 --- a/src/CLASS2/dihedral_class2.cpp +++ b/src/CLASS2/dihedral_class2.cpp @@ -26,20 +26,19 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.0000001 /* ---------------------------------------------------------------------- */ -DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp) -{ - PI = 4.0*atan(1.0); -} +DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp) {} /* ---------------------------------------------------------------------- */ @@ -697,8 +696,8 @@ void DihedralClass2::coeff(int narg, char **arg) at_f1_2[i] = f1_2_one; at_f2_2[i] = f2_2_one; at_f3_2[i] = f3_2_one; - at_theta0_1[i] = theta0_1_one/180.0 * PI; - at_theta0_2[i] = theta0_2_one/180.0 * PI; + at_theta0_1[i] = theta0_1_one/180.0 * MY_PI; + at_theta0_2[i] = theta0_2_one/180.0 * MY_PI; setflag_at[i] = 1; count++; } @@ -714,8 +713,8 @@ void DihedralClass2::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { aat_k[i] = k_one; - aat_theta0_1[i] = theta0_1_one/180.0 * PI; - aat_theta0_2[i] = theta0_2_one/180.0 * PI; + aat_theta0_1[i] = theta0_1_one/180.0 * MY_PI; + aat_theta0_2[i] = theta0_2_one/180.0 * MY_PI; setflag_aat[i] = 1; count++; } @@ -749,11 +748,11 @@ void DihedralClass2::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { k1[i] = k1_one; - phi1[i] = phi1_one/180.0 * PI; + phi1[i] = phi1_one/180.0 * MY_PI; k2[i] = k2_one; - phi2[i] = phi2_one/180.0 * PI; + phi2[i] = phi2_one/180.0 * MY_PI; k3[i] = k3_one; - phi3[i] = phi3_one/180.0 * PI; + phi3[i] = phi3_one/180.0 * MY_PI; setflag_d[i] = 1; count++; } diff --git a/src/CLASS2/dihedral_class2.h b/src/CLASS2/dihedral_class2.h index c99258a627..b7a519a27d 100644 --- a/src/CLASS2/dihedral_class2.h +++ b/src/CLASS2/dihedral_class2.h @@ -46,7 +46,6 @@ class DihedralClass2 : public Dihedral { double *bb13t_k,*bb13t_r10,*bb13t_r30; int *setflag_d,*setflag_mbt,*setflag_ebt; int *setflag_at,*setflag_aat,*setflag_bb13t; - double PI; void allocate(); }; diff --git a/src/CLASS2/improper_class2.cpp b/src/CLASS2/improper_class2.cpp index 7329870aec..c1331c607e 100644 --- a/src/CLASS2/improper_class2.cpp +++ b/src/CLASS2/improper_class2.cpp @@ -26,19 +26,18 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 /* ---------------------------------------------------------------------- */ -ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp) -{ - PI = 4.0*atan(1.0); -} +ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp) {} /* ---------------------------------------------------------------------- */ @@ -550,9 +549,9 @@ void ImproperClass2::coeff(int narg, char **arg) aa_k1[i] = k1_one; aa_k2[i] = k2_one; aa_k3[i] = k3_one; - aa_theta0_1[i] = theta0_1_one/180.0 * PI; - aa_theta0_2[i] = theta0_2_one/180.0 * PI; - aa_theta0_3[i] = theta0_3_one/180.0 * PI; + aa_theta0_1[i] = theta0_1_one/180.0 * MY_PI; + aa_theta0_2[i] = theta0_2_one/180.0 * MY_PI; + aa_theta0_3[i] = theta0_3_one/180.0 * MY_PI; setflag_aa[i] = 1; count++; } @@ -567,7 +566,7 @@ void ImproperClass2::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { k0[i] = k0_one; - chi0[i] = chi0_one/180.0 * PI; + chi0[i] = chi0_one/180.0 * MY_PI; setflag_i[i] = 1; count++; } diff --git a/src/CLASS2/improper_class2.h b/src/CLASS2/improper_class2.h index ed14c2ed86..cbee3ac810 100644 --- a/src/CLASS2/improper_class2.h +++ b/src/CLASS2/improper_class2.h @@ -38,7 +38,6 @@ class ImproperClass2 : public Improper { double *k0,*chi0; double *aa_k1,*aa_k2,*aa_k3,*aa_theta0_1,*aa_theta0_2,*aa_theta0_3; int *setflag_i,*setflag_aa; - double PI; void allocate(); void angleangle(int, int); diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp index aba3715cc1..ee5d7d3e32 100644 --- a/src/CLASS2/pair_lj_class2.cpp +++ b/src/CLASS2/pair_lj_class2.cpp @@ -19,10 +19,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -254,14 +256,13 @@ double PairLJClass2::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; - etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 3.0*rc3) / (3.0*rc6); - ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / rc6; } diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp index b6dc7d8018..9cd784ff58 100644 --- a/src/CLASS2/pair_lj_class2_coul_cut.cpp +++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp @@ -20,10 +20,12 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -307,14 +309,13 @@ double PairLJClass2CoulCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; - etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 3.0*rc3) / (3.0*rc6); - ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / rc6; } diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp index b9423c4728..34ff47d804 100644 --- a/src/CLASS2/pair_lj_class2_coul_long.cpp +++ b/src/CLASS2/pair_lj_class2_coul_long.cpp @@ -22,10 +22,12 @@ #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -321,14 +323,13 @@ double PairLJClass2CoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; - etail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 3.0*rc3) / (3.0*rc6); - ptail_ij = 2.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 2.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / rc6; } diff --git a/src/COLLOID/pair_lubricate.cpp b/src/COLLOID/pair_lubricate.cpp index 5eb072b93e..f3c9a0dc06 100644 --- a/src/COLLOID/pair_lubricate.cpp +++ b/src/COLLOID/pair_lubricate.cpp @@ -28,11 +28,13 @@ #include "neigh_list.h" #include "neigh_request.h" #include "update.h" -#include "memory.h" #include "random_mars.h" +#include "math_const.h" +#include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -73,7 +75,6 @@ void PairLubricate::compute(int eflag, int vflag) double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3; double a_squeeze,a_shear,a_pump,a_twist; int *ilist,*jlist,*numneigh,**firstneigh; - double PI = 4.0*atan(1.0); if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -190,16 +191,16 @@ void PairLubricate::compute(int eflag, int vflag) h_sep = r - 2.0*radi; if (flag1) - a_squeeze = (3.0*PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep); + a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/h_sep); if (flag2) - a_shear = (PI*mu*2.*radi/2.0) * + a_shear = (MY_PI*mu*2.*radi/2.0) * log(2.0*radi/2.0/h_sep)*(2.0*radi+h_sep)*(2.0*radi+h_sep)/4.0; if (flag3) - a_pump = (PI*mu*pow(2.0*radi,4)/8.0) * + a_pump = (MY_PI*mu*pow(2.0*radi,4)/8.0) * ((3.0/20.0) * log(2.0*radi/2.0/h_sep) + (63.0/250.0) * (h_sep/2.0/radi) * log(2.0*radi/2.0/h_sep)); if (flag4) - a_twist = (PI*mu*pow(2.0*radi,4)/4.0) * + a_twist = (MY_PI*mu*pow(2.0*radi,4)/4.0) * (h_sep/2.0/radi) * log(2.0/(2.0*h_sep)); if (h_sep >= cut_inner[itype][jtype]) { @@ -231,7 +232,7 @@ void PairLubricate::compute(int eflag, int vflag) torque[i][2] += vxmu2f * tz; } else { - a_squeeze = (3.0*PI*mu*2.0*radi/2.0) * + a_squeeze = (3.0*MY_PI*mu*2.0*radi/2.0) * (2.0*radi/4.0/cut_inner[itype][jtype]); fpair = -a_squeeze*vnnr; fpair *= vxmu2f; diff --git a/src/GPU/pppm_gpu.cpp b/src/GPU/pppm_gpu.cpp index 58c65b365e..0fa91a2518 100644 --- a/src/GPU/pppm_gpu.cpp +++ b/src/GPU/pppm_gpu.cpp @@ -32,10 +32,10 @@ #include "domain.h" #include "fft3d_wrap.h" #include "remap_wrap.h" -#include "memory.h" -#include "error.h" #include "gpu_extra.h" #include "math_const.h" +#include "memory.h" +#include "error.h" using namespace LAMMPS_NS; using namespace MathConst; @@ -191,7 +191,7 @@ void PPPMGPU::compute(int eflag, int vflag) energy *= 0.5*volume; energy -= g_ewald*qsqsum/1.772453851 + - 0.5*MY_PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp index 5e7a417462..fe0ce40f31 100644 --- a/src/GRANULAR/fix_pour.cpp +++ b/src/GRANULAR/fix_pour.cpp @@ -27,10 +27,12 @@ #include "region_block.h" #include "region_cylinder.h" #include "random_park.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EPSILON 0.001 @@ -54,8 +56,6 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : if (seed <= 0) error->all(FLERR,"Illegal fix pour command"); - PI = 4.0*atan(1.0); - // option defaults int iregion = -1; @@ -216,11 +216,11 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) : double dy = yhi - ylo; if (dy < 1.0) dy = 1.0; volume = (xhi-xlo) * dy * (zhi-zlo); - } else volume = PI*rc*rc * (zhi-zlo); - volume_one = 4.0/3.0 * PI * radius_hi*radius_hi*radius_hi; + } else volume = MY_PI*rc*rc * (zhi-zlo); + volume_one = 4.0/3.0 * MY_PI * radius_hi*radius_hi*radius_hi; } else { volume = (xhi-xlo) * (yhi-ylo); - volume_one = PI * radius_hi*radius_hi; + volume_one = MY_PI * radius_hi*radius_hi; } nper = static_cast (volfrac*volume/volume_one); @@ -476,7 +476,7 @@ void FixPour::pre_exchange() m = atom->nlocal - 1; atom->type[m] = ntype; atom->radius[m] = radtmp; - atom->rmass[m] = 4.0*PI/3.0 * radtmp*radtmp*radtmp * denstmp; + atom->rmass[m] = 4.0*MY_PI/3.0 * radtmp*radtmp*radtmp * denstmp; atom->mask[m] = 1 | groupbit; atom->v[m][0] = vxtmp; atom->v[m][1] = vytmp; diff --git a/src/GRANULAR/fix_pour.h b/src/GRANULAR/fix_pour.h index ec9590b276..1880597139 100644 --- a/src/GRANULAR/fix_pour.h +++ b/src/GRANULAR/fix_pour.h @@ -56,7 +56,6 @@ class FixPour : public Fix { int me,nprocs; int *recvcounts,*displs; - double PI; int nfreq,nfirst,ninserted,nper; double lo_current,hi_current; class FixShearHistory *fix_history; diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 0345274cb0..020425d110 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -26,10 +26,12 @@ #include "pair.h" #include "modify.h" #include "respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{XPLANE,YPLANE,ZPLANE,ZCYLINDER}; // XYZ PLANE need to be 0,1,2 enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY}; @@ -159,10 +161,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : // setup oscillations - if (wiggle) { - double PI = 4.0 * atan(1.0); - omega = 2.0*PI / period; - } + if (wiggle) omega = 2.0*MY_PI / period; // perform initial allocation of atom-based arrays // register with Atom class diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp index 5b6d46750a..edd030b55b 100644 --- a/src/KSPACE/ewald.cpp +++ b/src/KSPACE/ewald.cpp @@ -26,10 +26,12 @@ #include "force.h" #include "pair.h" #include "domain.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.00001 @@ -40,7 +42,6 @@ Ewald::Ewald(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg) if (narg != 1) error->all(FLERR,"Illegal kspace_style ewald command"); precision = atof(arg[0]); - PI = 4.0*atan(1.0); kmax = 0; kxvecs = kyvecs = kzvecs = NULL; @@ -165,17 +166,17 @@ void Ewald::setup() double zprd_slab = zprd*slab_volfactor; volume = xprd * yprd * zprd_slab; - unitk[0] = 2.0*PI/xprd; - unitk[1] = 2.0*PI/yprd; - unitk[2] = 2.0*PI/zprd_slab; + unitk[0] = 2.0*MY_PI/xprd; + unitk[1] = 2.0*MY_PI/yprd; + unitk[2] = 2.0*MY_PI/zprd_slab; // determine kmax // function of current box size, precision, G_ewald (short-range cutoff) - int nkxmx = static_cast ((g_ewald*xprd/PI) * sqrt(-log(precision))); - int nkymx = static_cast ((g_ewald*yprd/PI) * sqrt(-log(precision))); + int nkxmx = static_cast ((g_ewald*xprd/MY_PI) * sqrt(-log(precision))); + int nkymx = static_cast ((g_ewald*yprd/MY_PI) * sqrt(-log(precision))); int nkzmx = - static_cast ((g_ewald*zprd_slab/PI) * sqrt(-log(precision))); + static_cast ((g_ewald*zprd_slab/MY_PI) * sqrt(-log(precision))); int kmax_old = kmax; kmax = MAX(nkxmx,nkymx); @@ -281,9 +282,8 @@ void Ewald::compute(int eflag, int vflag) for (k = 0; k < kcount; k++) energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); - PI = 4.0*atan(1.0); energy -= g_ewald*qsqsum/1.772453851 + - 0.5*PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e*scale; } @@ -495,7 +495,7 @@ void Ewald::coeffs() double unitky = unitk[1]; double unitkz = unitk[2]; double g_ewald_sq_inv = 1.0 / (g_ewald*g_ewald); - double preu = 4.0*PI/volume; + double preu = 4.0*MY_PI/volume; kcount = 0; @@ -817,13 +817,13 @@ void Ewald::slabcorr(int eflag) // compute corrections - double e_slabcorr = 2.0*PI*dipole_all*dipole_all/volume; + double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume; if (eflag) energy += qqrd2e*scale * e_slabcorr; // add on force corrections - double ffact = -4.0*PI*dipole_all/volume; + double ffact = -4.0*MY_PI*dipole_all/volume; double **f = atom->f; for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*scale * q[i]*ffact; diff --git a/src/KSPACE/ewald.h b/src/KSPACE/ewald.h index 382dd26ee3..cd22f987f7 100644 --- a/src/KSPACE/ewald.h +++ b/src/KSPACE/ewald.h @@ -34,7 +34,6 @@ class Ewald : public KSpace { double memory_usage(); protected: - double PI; double precision; int kcount,kmax,kmax3d,kmax_created; double qqrd2e; diff --git a/src/KSPACE/pair_born_coul_long.cpp b/src/KSPACE/pair_born_coul_long.cpp index dca8532d35..2e607cd74d 100644 --- a/src/KSPACE/pair_born_coul_long.cpp +++ b/src/KSPACE/pair_born_coul_long.cpp @@ -26,10 +26,12 @@ #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -313,7 +315,6 @@ double PairBornCoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; @@ -321,11 +322,11 @@ double PairBornCoulLong::init_one(int i, int j) double rc2 = rc*rc; double rc3 = rc2*rc; double rc5 = rc3*rc2; - etail_ij = 2.0*PI*all[0]*all[1] * + etail_ij = 2.0*MY_PI*all[0]*all[1] * (a[i][j]*exp((sigma[i][j]-rc)/rho1)*rho1* (rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3) + d[i][j]/(5.0*rc5)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1] * + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1] * (-a[i][j]*exp((sigma[i][j]-rc)/rho1) * (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3 - 8.0*d[i][j]/(5.0*rc5)); diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp index 813b3b025a..a68029f367 100644 --- a/src/KSPACE/pair_buck_coul_long.cpp +++ b/src/KSPACE/pair_buck_coul_long.cpp @@ -22,10 +22,12 @@ #include "kspace.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -293,17 +295,16 @@ double PairBuckCoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; double rc = cut_lj[i][j]; double rc2 = rc*rc; double rc3 = rc2*rc; - etail_ij = 2.0*PI*all[0]*all[1]* + etail_ij = 2.0*MY_PI*all[0]*all[1]* (a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]* + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]* (-a[i][j]*exp(-rc/rho1)* (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3); } diff --git a/src/KSPACE/pair_lj_cut_coul_long.cpp b/src/KSPACE/pair_lj_cut_coul_long.cpp index ba9e390baa..ff8fb1fd22 100644 --- a/src/KSPACE/pair_lj_cut_coul_long.cpp +++ b/src/KSPACE/pair_lj_cut_coul_long.cpp @@ -30,10 +30,12 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define EWALD_F 1.12837917 #define EWALD_P 0.3275911 @@ -770,15 +772,14 @@ double PairLJCutCoulLong::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); } diff --git a/src/MAKE/Makefile.g++ b/src/MAKE/Makefile.g++ index c9480cd026..62f82e372a 100755 --- a/src/MAKE/Makefile.g++ +++ b/src/MAKE/Makefile.g++ @@ -6,10 +6,10 @@ SHELL = /bin/sh # compiler/linker settings # specify flags and libraries needed for your compiler -CC = g++4 +CC = g++ CCFLAGS = -g -O # -Wunused DEPFLAGS = -M -LINK = g++4 +LINK = g++ LINKFLAGS = -g -O LIB = ARCHIVE = ar @@ -35,7 +35,7 @@ LMP_INC = -DLAMMPS_GZIP -DLAMMPS_JPEG MPI_INC = -DMPICH_SKIP_MPICXX MPI_PATH = -MPI_LIB = -lmpich -lpthread +MPI_LIB = -lmpich -lmpl -lpthread # FFT library, OPTIONAL # see discussion in doc/Section_start.html#2_2 (step 6) @@ -57,7 +57,7 @@ FFT_LIB = -lfftw JPG_INC = JPG_PATH = -JPG_LIB = /usr/local/lib/libjpeg.a +JPG_LIB = -ljpeg # --------------------------------------------------------------------- # build rules and dependencies diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial index cc4480d79b..8849b18432 100755 --- a/src/MAKE/Makefile.serial +++ b/src/MAKE/Makefile.serial @@ -7,10 +7,10 @@ SHELL = /bin/sh # generally no need to edit this section # unless additional compiler/linker flags or libraries needed for your machine -CC = g++4 +CC = g++ CCFLAGS = -O DEPFLAGS = -M -LINK = g++4 +LINK = g++ LINKFLAGS = -O LIB = ARCHIVE = ar diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index eac19b515d..ec52038907 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -29,10 +29,12 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define MAXLINE 1024 #define TOL 1.0e-9 diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index 197e0bcd4d..c90898335c 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -29,12 +29,11 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" -#include "memory.h" -#include "error.h" #include "group.h" #include "update.h" - #include "math_const.h" +#include "memory.h" +#include "error.h" using namespace LAMMPS_NS; using namespace MathConst; diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h index 7093ea8ef1..b236ab7d08 100644 --- a/src/MANYBODY/pair_comb.h +++ b/src/MANYBODY/pair_comb.h @@ -58,7 +58,6 @@ class PairComb : public Pair { int powermint; }; - double PI,PI2,PI4,PIsq; double cutmax; // max cutoff for all elements int nelements; // # of unique elements char **elements; // names of unique elements diff --git a/src/MANYBODY/pair_tersoff.h b/src/MANYBODY/pair_tersoff.h index 411ddf8871..0d2cf1f32b 100644 --- a/src/MANYBODY/pair_tersoff.h +++ b/src/MANYBODY/pair_tersoff.h @@ -63,7 +63,8 @@ class PairTersoff : public Pair { void setup(); virtual void repulsive(Param *, double, double &, int, double &); double zeta(Param *, double, double, double *, double *); - virtual void force_zeta(Param *, double, double, double &, double &, int, double &); + virtual void force_zeta(Param *, double, double, double &, + double &, int, double &); void attractive(Param *, double, double, double, double *, double *, double *, double *, double *); @@ -74,7 +75,15 @@ class PairTersoff : public Pair { double ters_bij(double, Param *); double ters_bij_d(double, Param *); - inline double ters_gijk(const double costheta, const Param * const param) const { + void ters_zetaterm_d(double, double *, double, double *, double, + double *, double *, double *, Param *); + void costheta_d(double *, double, double *, double, + double *, double *, double *); + + // inlined functions for efficiency + + inline double ters_gijk(const double costheta, + const Param * const param) const { const double ters_c = param->c * param->c; const double ters_d = param->d * param->d; const double hcth = param->h - costheta; @@ -82,7 +91,8 @@ class PairTersoff : public Pair { return param->gamma*(1.0 + ters_c/ters_d - ters_c / (ters_d + hcth*hcth)); } - inline double ters_gijk_d(const double costheta, const Param * const param) const { + inline double ters_gijk_d(const double costheta, + const Param * const param) const { const double ters_c = param->c * param->c; const double ters_d = param->d * param->d; const double hcth = param->h - costheta; @@ -91,13 +101,6 @@ class PairTersoff : public Pair { return param->gamma*numerator*denominator*denominator; } - void ters_zetaterm_d(double, double *, double, double *, double, - double *, double *, double *, Param *); - void costheta_d(double *, double, double *, double, - double *, double *, double *); - - // vector functions, inline for efficiency - inline double vec3_dot(const double x[3], const double y[3]) const { return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]; } diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index 9016a26b28..9c8654100d 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -30,10 +30,12 @@ #include "random_park.h" #include "force.h" #include "pair.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -71,10 +73,9 @@ FixGCMC::FixGCMC(LAMMPS *lmp, int narg, char **arg) : // compute beta, lambda, sigma, and the zz factor beta = 1.0/(force->boltz*reservoir_temperature); - double PI = 4.0*atan(1.0); double gas_mass = atom->mass[ntype]; double lambda = sqrt(force->hplanck*force->hplanck/ - (2.0*PI*gas_mass*force->mvv2e* + (2.0*MY_PI*gas_mass*force->mvv2e* force->boltz*reservoir_temperature)); sigma = sqrt(force->boltz*reservoir_temperature/gas_mass/force->mvv2e); zz = exp(beta*chemical_potential)/(pow(lambda,3)); diff --git a/src/MOLECULE/angle_charmm.cpp b/src/MOLECULE/angle_charmm.cpp index 5dd81580cc..0361209e66 100644 --- a/src/MOLECULE/angle_charmm.cpp +++ b/src/MOLECULE/angle_charmm.cpp @@ -23,10 +23,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -209,7 +211,7 @@ void AngleCharmm::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; k_ub[i] = k_ub_one; r_ub[i] = r_ub_one; setflag[i] = 1; diff --git a/src/MOLECULE/angle_cosine.cpp b/src/MOLECULE/angle_cosine.cpp index fb523628be..596903c18e 100644 --- a/src/MOLECULE/angle_cosine.cpp +++ b/src/MOLECULE/angle_cosine.cpp @@ -19,10 +19,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -174,7 +176,7 @@ void AngleCosine::coeff(int narg, char **arg) double AngleCosine::equilibrium_angle(int i) { - return PI; + return MY_PI; } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/angle_cosine_periodic.cpp b/src/MOLECULE/angle_cosine_periodic.cpp index d401c1fffc..8aaf54cb9f 100644 --- a/src/MOLECULE/angle_cosine_periodic.cpp +++ b/src/MOLECULE/angle_cosine_periodic.cpp @@ -23,10 +23,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -226,7 +228,7 @@ void AngleCosinePeriodic::coeff(int narg, char **arg) double AngleCosinePeriodic::equilibrium_angle(int i) { - return PI; + return MY_PI; } /* ---------------------------------------------------------------------- diff --git a/src/MOLECULE/angle_cosine_squared.cpp b/src/MOLECULE/angle_cosine_squared.cpp index 9262700679..95c1a3b922 100644 --- a/src/MOLECULE/angle_cosine_squared.cpp +++ b/src/MOLECULE/angle_cosine_squared.cpp @@ -23,10 +23,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -178,7 +180,7 @@ void AngleCosineSquared::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; setflag[i] = 1; count++; } diff --git a/src/MOLECULE/angle_harmonic.cpp b/src/MOLECULE/angle_harmonic.cpp index e3def97499..8a462abaed 100644 --- a/src/MOLECULE/angle_harmonic.cpp +++ b/src/MOLECULE/angle_harmonic.cpp @@ -19,10 +19,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -178,7 +180,7 @@ void AngleHarmonic::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; setflag[i] = 1; count++; } diff --git a/src/MOLECULE/angle_table.cpp b/src/MOLECULE/angle_table.cpp index 4395c20413..a8e6254500 100644 --- a/src/MOLECULE/angle_table.cpp +++ b/src/MOLECULE/angle_table.cpp @@ -24,10 +24,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{LINEAR,SPLINE}; @@ -238,8 +240,8 @@ void AngleTable::coeff(int narg, char **arg) // convert theta from degrees to radians for (int i = 0; i < tb->ninput; i++){ - tb->afile[i] *= PI/180.0; - tb->ffile[i] *= 180.0/PI; + tb->afile[i] *= MY_PI/180.0; + tb->ffile[i] *= 180.0/MY_PI; } // spline read-in and compute a,e,f vectors within table @@ -442,7 +444,7 @@ void AngleTable::compute_table(Table *tb) // delta = table spacing in angle for N-1 bins int tlm1 = tablength-1; - tb->delta = PI/ tlm1; + tb->delta = MY_PI / tlm1; tb->invdelta = 1.0/tb->delta; tb->deltasq6 = tb->delta*tb->delta / 6.0; @@ -501,8 +503,8 @@ void AngleTable::param_extract(Table *tb, char *line) tb->fplo = atof(word); word = strtok(NULL," \t\n\r\f"); tb->fphi = atof(word); - tb->fplo *= (180.0/PI)*(180.0/PI); - tb->fphi *= (180.0/PI)*(180.0/PI); + tb->fplo *= (180.0/MY_PI)*(180.0/MY_PI); + tb->fphi *= (180.0/MY_PI)*(180.0/MY_PI); } else if (strcmp(word,"EQ") == 0) { word = strtok(NULL," \t\n\r\f"); tb->theta0 = atof(word); diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp index a404311150..c762a56ad5 100644 --- a/src/MOLECULE/dihedral_charmm.cpp +++ b/src/MOLECULE/dihedral_charmm.cpp @@ -27,10 +27,12 @@ #include "force.h" #include "pair.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 @@ -344,14 +346,12 @@ void DihedralCharmm::coeff(int narg, char **arg) if (weight_one < 0.0 || weight_one > 1.0) error->all(FLERR,"Incorrect weight arg for dihedral coefficients"); - double PI = 4.0*atan(1.0); - int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; shift[i] = shift_one; - cos_shift[i] = cos(PI*shift_one/180.0); - sin_shift[i] = sin(PI*shift_one/180.0); + cos_shift[i] = cos(MY_PI*shift_one/180.0); + sin_shift[i] = sin(MY_PI*shift_one/180.0); multiplicity[i] = multiplicity_one; weight[i] = weight_one; setflag[i] = 1; @@ -420,10 +420,9 @@ void DihedralCharmm::read_restart(FILE *fp) MPI_Bcast(&shift[1],atom->ndihedraltypes,MPI_INT,0,world); MPI_Bcast(&weight[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - double PI = 4.0*atan(1.0); for (int i = 1; i <= atom->ndihedraltypes; i++) { setflag[i] = 1; - cos_shift[i] = cos(PI*shift[i]/180.0); - sin_shift[i] = sin(PI*shift[i]/180.0); + cos_shift[i] = cos(MY_PI*shift[i]/180.0); + sin_shift[i] = sin(MY_PI*shift[i]/180.0); } } diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp index 7a50eb4fc0..ee93d2a08d 100644 --- a/src/MOLECULE/dihedral_helix.cpp +++ b/src/MOLECULE/dihedral_helix.cpp @@ -27,10 +27,12 @@ #include "comm.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -192,9 +194,9 @@ void DihedralHelix::compute(int eflag, int vflag) siinv = 1.0/si; p = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) + - cphi[type]*(1.0 + cos(phi + 0.25*PI)); + cphi[type]*(1.0 + cos(phi + MY_PI4)); pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + - cphi[type]*sin(phi + 0.25*PI)*siinv; + cphi[type]*sin(phi + MY_PI4)*siinv; if (eflag) edihedral = p; diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp index 62d5cd54b6..87d94079bd 100644 --- a/src/MOLECULE/improper_harmonic.cpp +++ b/src/MOLECULE/improper_harmonic.cpp @@ -22,10 +22,12 @@ #include "domain.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -248,7 +250,7 @@ void ImproperHarmonic::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { k[i] = k_one; - chi[i] = chi_one/180.0 * PI; + chi[i] = chi_one/180.0 * MY_PI; setflag[i] = 1; count++; } diff --git a/src/MOLECULE/improper_umbrella.cpp b/src/MOLECULE/improper_umbrella.cpp index 34fddf708a..97a127b318 100644 --- a/src/MOLECULE/improper_umbrella.cpp +++ b/src/MOLECULE/improper_umbrella.cpp @@ -25,10 +25,12 @@ #include "domain.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -269,7 +271,7 @@ void ImproperUmbrella::coeff(int narg, char **arg) int count = 0; for (int i = ilo; i <= ihi; i++) { kw[i] = k_one; - w0[i] = w_one/180.0 * PI; + w0[i] = w_one/180.0 * MY_PI; if (w_one == 0) C[i] = 1.0; else C[i] = kw[i]/(pow(sin(w0[i]),2)); setflag[i] = 1; diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp index 0898c355c8..104cf83e6d 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp @@ -26,11 +26,13 @@ #include "neighbor.h" #include "neigh_request.h" #include "neigh_list.h" +#include "domain.h" +#include "math_const.h" #include "memory.h" #include "error.h" -#include "domain.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 #define CHUNK 8 @@ -44,8 +46,6 @@ PairHbondDreidingLJ::PairHbondDreidingLJ(LAMMPS *lmp) : Pair(lmp) no_virial_fdotr_compute = 1; - PI = 4.0*atan(1.0); - nparams = maxparam = 0; params = NULL; @@ -76,7 +76,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) { int i,j,k,m,ii,jj,kk,inum,jnum,knum,itype,jtype,ktype; double delx,dely,delz,rsq,rsq1,rsq2,r1,r2; - double factor_hb,force_angle,force_kernel,evdwl,evdwl_total,eng_lj; + double factor_hb,force_angle,force_kernel,evdwl,eng_lj,ehbond; double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double fi[3],fj[3],delr1[3],delr2[3]; double r2inv,r10inv; @@ -84,7 +84,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) int *ilist,*jlist,*klist,*numneigh,**firstneigh; Param *pm; - evdwl_total = evdwl = 0.0; + evdwl = ehbond = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -159,7 +159,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) if (c < -1.0) c = -1.0; ac = acos(c); - if (ac > pm->cut_angle && ac < (2.0*PI - pm->cut_angle)) { + if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) { s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; @@ -186,6 +186,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) if (eflag) { evdwl = eng_lj * pow(c,pm->ap); evdwl *= factor_hb; + ehbond += evdwl; } a = factor_hb*force_angle/s; @@ -223,13 +224,9 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) // KIJ instead of IJK b/c delr1/delr2 are both with respect to k - if (evflag) { - ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2); - if (eflag_global) { - hbcount++; - evdwl_total += evdwl; - } - } + if (evflag) ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2); + + hbcount++; } } } @@ -238,7 +235,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) if (eflag_global) { pvector[0] = hbcount; - pvector[1] = evdwl_total; + pvector[1] = ehbond; } } @@ -282,7 +279,7 @@ void PairHbondDreidingLJ::settings(int narg, char **arg) ap_global = force->inumeric(arg[0]); cut_inner_global = force->numeric(arg[1]); cut_outer_global = force->numeric(arg[2]); - cut_angle_global = force->numeric(arg[3]) * PI/180.0; + cut_angle_global = force->numeric(arg[3]) * MY_PI/180.0; } /* ---------------------------------------------------------------------- @@ -319,7 +316,7 @@ void PairHbondDreidingLJ::coeff(int narg, char **arg) if (cut_inner_one>cut_outer_one) error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); double cut_angle_one = cut_angle_global; - if (narg == 10) cut_angle_one = force->numeric(arg[9]) * PI/180.0; + if (narg == 10) cut_angle_one = force->numeric(arg[9]) * MY_PI/180.0; // grow params array if necessary if (nparams == maxparam) { @@ -503,7 +500,7 @@ double PairHbondDreidingLJ::single(int i, int j, int itype, int jtype, if (c < -1.0) c = -1.0; ac = acos(c); - if (ac < pm->cut_angle || ac > (2.0*PI - pm->cut_angle)) return 0.0; + if (ac < pm->cut_angle || ac > (2.0*MY_PI - pm->cut_angle)) return 0.0; s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.h b/src/MOLECULE/pair_hbond_dreiding_lj.h index 387cd3f095..1304743b8d 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.h +++ b/src/MOLECULE/pair_hbond_dreiding_lj.h @@ -38,7 +38,6 @@ class PairHbondDreidingLJ : public Pair { protected: double cut_inner_global,cut_outer_global,cut_angle_global; int ap_global; - double PI; struct Param { double epsilon,sigma; diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp index 416595cbff..e7f9c1e7c5 100644 --- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp @@ -26,11 +26,13 @@ #include "neighbor.h" #include "neigh_request.h" #include "neigh_list.h" +#include "domain.h" +#include "math_const.h" #include "memory.h" #include "error.h" -#include "domain.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 #define CHUNK 8 @@ -46,14 +48,14 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) { int i,j,k,m,ii,jj,kk,inum,jnum,knum,itype,jtype,ktype; double delx,dely,delz,rsq,rsq1,rsq2,r1,r2; - double factor_hb,force_angle,force_kernel,evdwl,evdwl_total; + double factor_hb,force_angle,force_kernel,evdwl,ehbond; double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double fi[3],fj[3],delr1[3],delr2[3]; double r,dr,dexp,eng_morse,switch1,switch2; int *ilist,*jlist,*klist,*numneigh,**firstneigh; Param *pm; - evdwl_total = evdwl = 0.0; + evdwl = ehbond = 0.0; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -128,7 +130,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) if (c < -1.0) c = -1.0; ac = acos(c); - if (ac > pm->cut_angle && ac < (2.0*PI - pm->cut_angle)) { + if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) { s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; @@ -154,6 +156,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) if (eflag) { evdwl = eng_morse * pow(c,params[m].ap); evdwl *= factor_hb; + ehbond += evdwl; } a = factor_hb*force_angle/s; @@ -190,13 +193,10 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) f[k][2] -= vz1 + vz2; // KIJ instead of IJK b/c delr1/delr2 are both with respect to k - if (evflag) { - ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2); - if (eflag_global) { - hbcount++; - evdwl_total += evdwl; - } - } + + if (evflag) ev_tally3(k,i,j,evdwl,0.0,fi,fj,delr1,delr2); + + hbcount++; } } } @@ -205,7 +205,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) if (eflag_global) { pvector[0] = hbcount; - pvector[1] = evdwl_total; + pvector[1] = ehbond; } } @@ -244,7 +244,7 @@ void PairHbondDreidingMorse::coeff(int narg, char **arg) if (cut_inner_one>cut_outer_one) error->all(FLERR,"Pair inner cutoff >= Pair outer cutoff"); double cut_angle_one = cut_angle_global; - if (narg > 10) cut_angle_one = force->numeric(arg[10]) * PI/180.0; + if (narg > 10) cut_angle_one = force->numeric(arg[10]) * MY_PI/180.0; // grow params array if necessary @@ -406,7 +406,7 @@ double PairHbondDreidingMorse::single(int i, int j, int itype, int jtype, if (c < -1.0) c = -1.0; ac = acos(c); - if (ac < pm->cut_angle || ac > (2.0*PI - pm->cut_angle)) return 0.0; + if (ac < pm->cut_angle || ac > (2.0*MY_PI - pm->cut_angle)) return 0.0; s = sqrt(1.0 - c*c); if (s < SMALL) s = SMALL; diff --git a/src/SHOCK/fix_append_atoms.cpp b/src/SHOCK/fix_append_atoms.cpp index 42fd494f96..9d59470f0d 100644 --- a/src/SHOCK/fix_append_atoms.cpp +++ b/src/SHOCK/fix_append_atoms.cpp @@ -64,38 +64,52 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR,"Only zhi currently implemented for append_atoms"); xloflag = 1; iarg++; - if (domain->boundary[0][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum the append boundary"); + if (domain->boundary[0][0] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"xhi") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); xhiflag = 1; iarg++; - if (domain->boundary[0][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[0][1] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"ylo") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); yloflag = 1; iarg++; - if (domain->boundary[1][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[1][0] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"yhi") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); yhiflag = 1; iarg++; - if (domain->boundary[1][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[1][1] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"zlo") == 0) { error->all(FLERR,"Only zhi currently implemented for append_atom"); zloflag = 1; iarg++; - if (domain->boundary[2][0] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[2][0] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"zhi") == 0) { zhiflag = 1; iarg++; - if (domain->boundary[2][1] != 3) error->all(FLERR,"Must shrink-wrap with minimum th append boundary"); + if (domain->boundary[2][1] != 3) + error->all(FLERR, + "Must shrink-wrap with minimum the append boundary"); } else if (strcmp(arg[iarg],"freq") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command"); freq = atoi(arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"spatial") == 0) { if (iarg+3 > narg) error->all(FLERR,"Illegal fix append_atoms command"); - if (strcmp(arg[iarg+1],"f_") == 0) error->all(FLERR,"Bad fix ID in fix append_atoms command"); + if (strcmp(arg[iarg+1],"f_") == 0) + error->all(FLERR, + "Bad fix ID in fix append_atoms command"); spatflag = 1; int n = strlen(arg[iarg+1]); spatlead = atof(arg[iarg+2]); @@ -106,7 +120,7 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : strcpy(spatialid,suffix); delete [] suffix; iarg += 3; - // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL + // NEED TO CHECK TO MAKE SURE FIX IS AN AVE/SPATIAL } else if (strcmp(arg[iarg],"size") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix append_atoms command"); size = atof(arg[iarg+1]); @@ -152,7 +166,8 @@ FixAppendAtoms::FixAppendAtoms(LAMMPS *lmp, int narg, char **arg) : if ((zloflag || zhiflag) && domain->zperiodic) error->all(FLERR,"Cannot use append_atoms in periodic dimension"); - if (domain->triclinic == 1) error->all(FLERR,"Cannot append atoms to a triclinic box"); + if (domain->triclinic == 1) + error->all(FLERR,"Cannot append atoms to a triclinic box"); // setup scaling diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp index ec0d07d20d..b673b9b7b5 100644 --- a/src/SRD/fix_srd.cpp +++ b/src/SRD/fix_srd.cpp @@ -22,6 +22,8 @@ #include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "group.h" #include "update.h" #include "force.h" @@ -34,13 +36,15 @@ #include "fix_wall_srd.h" #include "random_mars.h" #include "random_park.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{SLIP,NOSLIP}; -enum{SPHERE,ELLIPSOID,WALL}; +enum{SPHERE,ELLIPSOID,LINE,TRIANGLE,WALL}; enum{INSIDE_ERROR,INSIDE_WARN,INSIDE_IGNORE}; enum{BIG_MOVE,SRD_MOVE,SRD_ROTATE}; enum{CUBIC_ERROR,CUBIC_WARN}; @@ -48,10 +52,13 @@ enum{SHIFT_NO,SHIFT_YES,SHIFT_POSSIBLE}; enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp -#define INERTIA 0.4 -#define ATOMPERBIN 10 +#define EINERTIA 0.2 // moment of inertia prefactor for ellipsoid + +#define ATOMPERBIN 30 #define BIG 1.0e20 #define VBINSIZE 5 +#define TOLERANCE 0.00001 +#define MAXITER 20 //#define SRD_DEBUG 1 //#define SRD_DEBUG_ATOMID 58 @@ -93,7 +100,7 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) cubictol = 0.01; shiftuser = SHIFT_NO; shiftseed = 0; - streamflag = 1; + tstat = 0; int iarg = 8; while (iarg < narg) { @@ -154,10 +161,10 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) else error->all(FLERR,"Illegal fix srd command"); shiftseed = atoi(arg[iarg+2]); iarg += 3; - } else if (strcmp(arg[iarg],"stream") == 0) { + } else if (strcmp(arg[iarg],"tstat") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix srd command"); - if (strcmp(arg[iarg+1],"yes") == 0) streamflag = 1; - else if (strcmp(arg[iarg+1],"no") == 0) streamflag = 0; + if (strcmp(arg[iarg+1],"no") == 0) tstat = 0; + else if (strcmp(arg[iarg+1],"yes") == 0) tstat = 1; else error->all(FLERR,"Illegal fix srd command"); iarg += 2; } else error->all(FLERR,"Illegal fix srd command"); @@ -166,7 +173,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) // error check if (nevery <= 0) error->all(FLERR,"Illegal fix srd command"); - if (bigexist && biggroup < 0) error->all(FLERR,"Could not find fix srd group ID"); + if (bigexist && biggroup < 0) + error->all(FLERR,"Could not find fix srd group ID"); if (gridsrd <= 0.0) error->all(FLERR,"Illegal fix srd command"); if (temperature_srd <= 0.0) error->all(FLERR,"Illegal fix srd command"); if (seed <= 0) error->all(FLERR,"Illegal fix srd command"); @@ -174,7 +182,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) if (maxbounceallow < 0) error->all(FLERR,"Illegal fix srd command"); if (lamdaflag && lamda <= 0.0) error->all(FLERR,"Illegal fix srd command"); if (gridsearch <= 0.0) error->all(FLERR,"Illegal fix srd command"); - if (cubictol < 0.0 || cubictol > 1.0) error->all(FLERR,"Illegal fix srd command"); + if (cubictol < 0.0 || cubictol > 1.0) + error->all(FLERR,"Illegal fix srd command"); if ((shiftuser == SHIFT_YES || shiftuser == SHIFT_POSSIBLE) && shiftseed <= 0) error->all(FLERR,"Illegal fix srd command"); @@ -234,6 +243,8 @@ FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) // atom style pointers to particles that store bonus info avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + avec_line = (AtomVecLine *) atom->style_match("line"); + avec_tri = (AtomVecTri *) atom->style_match("tri"); // fix parameters @@ -287,7 +298,8 @@ void FixSRD::init() { // error checks - if (force->newton_pair == 0) error->all(FLERR,"Fix srd requires newton pair on"); + if (force->newton_pair == 0) + error->all(FLERR,"Fix srd requires newton pair on"); if (bigexist && comm->ghost_velocity == 0) error->all(FLERR,"Fix srd requires ghost atoms store velocity"); if (bigexist && collidestyle == NOSLIP && !atom->torque_flag) @@ -317,19 +329,21 @@ void FixSRD::init() fwall = wallfix->fwall; walltrigger = 0.5 * neighbor->skin; if (wallfix->overlap && overlap == 0 && me == 0) - error->warning(FLERR,"Fix SRD walls overlap but fix srd overlap not set"); + error->warning(FLERR, + "Fix SRD walls overlap but fix srd overlap not set"); } } // set change_flags if box size or shape changes - change_size = change_shape = 0; + change_size = change_shape = deformflag = 0; if (domain->nonperiodic == 2) change_size = 1; for (int i = 0; i < modify->nfix; i++) if (modify->fix[i]->box_change) { if (modify->fix[i]->box_change_size) change_size = 1; if (modify->fix[i]->box_change_shape) change_shape = 1; if (strcmp(modify->fix[i]->style,"deform") == 0) { + deformflag = 1; FixDeform *deform = (FixDeform *) modify->fix[i]; if (deform->box_change_shape && deform->remapflag != V_REMAP) error->all(FLERR,"Using fix srd with inconsistent " @@ -337,6 +351,10 @@ void FixSRD::init() } } + if (deformflag && tstat == 0 && me == 0) + error->warning(FLERR, + "Using fix srd with box deformation but no SRD thermostat"); + // parameterize based on current box volume dimension = domain->dimension; @@ -389,7 +407,8 @@ void FixSRD::setup(int vflag) setup_bounds(); if (dist_srd_reneigh < nevery*dt_big*vmax && me == 0) - error->warning(FLERR,"Fix srd SRD moves may trigger frequent reneighboring"); + error->warning(FLERR, + "Fix srd SRD moves may trigger frequent reneighboring"); // setup search bins and search stencil based on these distances @@ -405,6 +424,7 @@ void FixSRD::setup(int vflag) reneighflag = BIG_MOVE; pre_neighbor(); } + /* ---------------------------------------------------------------------- assign SRD particles to bins assign big particles to all bins they overlap @@ -414,6 +434,7 @@ void FixSRD::pre_neighbor() { int i,j,m,ix,iy,iz,jx,jy,jz,ibin,jbin,lo,hi; double rsq,cutbinsq; + double xlamda[3]; // grow SRD per-atom bin arrays if necessary @@ -559,7 +580,8 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-xblo2)*bininv2x); if (hi < 0) continue; - if (hi >= nbin2x) error->all(FLERR,"Fix SRD: bad search bin assignment"); + if (hi >= nbin2x) error->all(FLERR, + "Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-xblo2)*bininv2x); @@ -581,7 +603,8 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-yblo2)*bininv2y); if (hi < 0) continue; - if (hi >= nbin2y) error->all(FLERR,"Fix SRD: bad search bin assignment"); + if (hi >= nbin2y) error->all(FLERR, + "Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-yblo2)*bininv2y); @@ -603,7 +626,8 @@ void FixSRD::pre_neighbor() if (side == 0) { hi = static_cast ((xwall[m]+delta-zblo2)*bininv2z); if (hi < 0) continue; - if (hi >= nbin2z) error->all(FLERR,"Fix SRD: bad search bin assignment"); + if (hi >= nbin2z) error->all(FLERR, + "Fix SRD: bad search bin assignment"); lo = 0; } else { lo = static_cast ((xwall[m]-delta-zblo2)*bininv2z); @@ -643,6 +667,7 @@ void FixSRD::pre_neighbor() void FixSRD::post_force(int vflag) { int i,m,ix,iy,iz; + double xlamda[3]; // zero per-timestep stats @@ -763,19 +788,20 @@ void FixSRD::post_force(int vflag) /* ---------------------------------------------------------------------- reset SRD velocities - may perform random shifting by 1/2 bin in each dimension + may perform random shifting by up to 1/2 bin in each dimension called at pre-neighbor stage when all SRDs are now inside my sub-domain - for triclinic, will set mean velocity to box deformation velocity + if tstat, then thermostat SRD particles as well, including streaming effects ------------------------------------------------------------------------- */ void FixSRD::reset_velocities() { int i,j,n,ix,iy,iz,ibin,axis,sign,irandom; - double u[3],vave[3]; - double vx,vy,vz,vsq; - double *vold,*vnew,*xlamda; + double u[3],vsum[3]; + double vx,vy,vz,vsq,tbin,scale; + double *vave,*vnew,*xlamda; + double vstream[3]; - // if requested, perform a dynamic shift + // if requested, perform a dynamic shift of bin positions if (shiftflag) { double *boxlo; @@ -829,39 +855,23 @@ void FixSRD::reset_velocities() if (triclinic) domain->lamda2x(nlocal); - if (triclinic && streamflag) { - double *h_rate = domain->h_rate; - double *h_ratelo = domain->h_ratelo; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - xlamda = x[i]; - v[i][0] -= h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + - h_rate[4]*xlamda[2] + h_ratelo[0]; - v[i][1] -= h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1]; - v[i][2] -= h_rate[2]*xlamda[2] + h_ratelo[2]; - } - } - // for each bin I have particles contributing to: - // compute ave v and v^2 of particles in that bin + // compute summed v of particles in that bin // if I own the bin, set its random value, else set to 0.0 for (i = 0; i < nbins; i++) { n = 0; - vave[0] = vave[1] = vave[2] = 0.0; + vsum[0] = vsum[1] = vsum[2] = 0.0; for (j = binhead[i]; j >= 0; j = binnext[j]) { - vx = v[j][0]; - vy = v[j][1]; - vz = v[j][2]; - vave[0] += vx; - vave[1] += vy; - vave[2] += vz; + vsum[0] += v[j][0]; + vsum[1] += v[j][1]; + vsum[2] += v[j][2]; n++; } - vbin[i].vave[0] = vave[0]; - vbin[i].vave[1] = vave[1]; - vbin[i].vave[2] = vave[2]; + vbin[i].vsum[0] = vsum[0]; + vbin[i].vsum[1] = vsum[1]; + vbin[i].vsum[2] = vsum[2]; vbin[i].n = n; if (vbin[i].owner) vbin[i].random = random->uniform(); else vbin[i].random = 0.0; @@ -872,24 +882,43 @@ void FixSRD::reset_velocities() if (shifts[shiftflag].commflag) vbin_comm(shiftflag); // for each bin I have particles contributing to: - // reassign particle velocity by rotation around a random axis - // accumulate T_srd for each bin I own - // for triclinic, replace mean velocity with stream velocity + // compute vave over particles in bin + // thermal velocity of each particle = v - vave + // rotate thermal vel of each particle around one of 6 random axes + // add vave back to each particle + // thermostat if requested: + // if no deformation, rescale thermal vel to temperature + // if deformation, rescale thermal vel and change vave to vstream + // these are settings for extra dof_temp, dof_tstat to subtract + // (not sure why these settings work best) + // no deformation, no tstat: dof_temp = 1 + // yes deformation, no tstat: doesn't matter, system will not equilibrate + // no deformation, yes tstat: dof_temp = dof_tstat = 1 + // yes deformation, yes tstat: dof_temp = dof_tstat = 0 + // accumulate final T_srd for each bin I own + + double tfactor = force->mvv2e * mass_srd / (dimension * force->boltz); + int dof_temp = 1; + int dof_tstat; + if (tstat) { + if (deformflag) dof_tstat = dof_temp = 0; + else dof_tstat = 1; + } srd_bin_temp = 0.0; srd_bin_count = 0; if (dimension == 2) axis = 2; + double *h_rate = domain->h_rate; + double *h_ratelo = domain->h_ratelo; for (i = 0; i < nbins; i++) { n = vbin[i].n; if (n == 0) continue; - vold = vbin[i].vave; - vold[0] /= n; - vold[1] /= n; - vold[2] /= n; - - vnew = vold; + vave = vbin[i].vsum; + vave[0] /= n; + vave[1] /= n; + vave[2] /= n; irandom = static_cast (6.0*vbin[i].random); sign = irandom % 2; @@ -898,47 +927,63 @@ void FixSRD::reset_velocities() vsq = 0.0; for (j = binhead[i]; j >= 0; j = binnext[j]) { if (axis == 0) { - u[0] = v[j][0]-vold[0]; - u[1] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2]; - u[2] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1]; + u[0] = v[j][0]-vave[0]; + u[1] = sign ? v[j][2]-vave[2] : vave[2]-v[j][2]; + u[2] = sign ? vave[1]-v[j][1] : v[j][1]-vave[1]; } else if (axis == 1) { - u[1] = v[j][1]-vold[1]; - u[0] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2]; - u[2] = sign ? vold[0]-v[j][0] : v[j][0]-vold[0]; + u[1] = v[j][1]-vave[1]; + u[0] = sign ? v[j][2]-vave[2] : vave[2]-v[j][2]; + u[2] = sign ? vave[0]-v[j][0] : v[j][0]-vave[0]; } else { - u[2] = v[j][2]-vold[2]; - u[1] = sign ? v[j][0]-vold[0] : vold[0]-v[j][0]; - u[0] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1]; + u[2] = v[j][2]-vave[2]; + u[1] = sign ? v[j][0]-vave[0] : vave[0]-v[j][0]; + u[0] = sign ? vave[1]-v[j][1] : v[j][1]-vave[1]; } vsq += u[0]*u[0] + u[1]*u[1] + u[2]*u[2]; - v[j][0] = u[0] + vnew[0]; - v[j][1] = u[1] + vnew[1]; - v[j][2] = u[2] + vnew[2]; + v[j][0] = u[0] + vave[0]; + v[j][1] = u[1] + vave[1]; + v[j][2] = u[2] + vave[2]; + } + + if (tstat && n > 1) { + if (deformflag) { + xlamda = vbin[i].xctr; + vstream[0] = h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + + h_rate[4]*xlamda[2] + h_ratelo[0]; + vstream[1] = h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1]; + vstream[2] = h_rate[2]*xlamda[2] + h_ratelo[2]; + } else { + vstream[0] = vave[0]; + vstream[1] = vave[1]; + vstream[2] = vave[2]; + } + + // tbin = thermal temperature of particles in bin + // scale = scale factor for thermal velocity + + tbin = vsq/(n-dof_tstat) * tfactor; + scale = sqrt(temperature_srd/tbin); + + vsq = 0.0; + for (j = binhead[i]; j >= 0; j = binnext[j]) { + u[0] = (v[j][0] - vave[0]) * scale; + u[1] = (v[j][1] - vave[1]) * scale; + u[2] = (v[j][2] - vave[2]) * scale; + vsq += u[0]*u[0] + u[1]*u[1] + u[2]*u[2]; + v[j][0] = u[0] + vstream[0]; + v[j][1] = u[1] + vstream[1]; + v[j][2] = u[2] + vstream[2]; + } } // sum partial contribution of my particles to T even if I don't own bin - // but only count bin if I own it, so that bin is counted exactly once + // but only count bin if I own it, so each bin is counted exactly once - if (n > 1) { - srd_bin_temp += vsq / (n-1); - if (vbin[i].owner) srd_bin_count++; - } + if (n > 1) srd_bin_temp += vsq/(n-dof_temp); + if (vbin[i].owner) srd_bin_count++; } - srd_bin_temp *= force->mvv2e * mass_srd / (dimension * force->boltz); - - if (triclinic && streamflag) { - double *h_rate = domain->h_rate; - double *h_ratelo = domain->h_ratelo; - for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - xlamda = x[i]; - v[i][0] += h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + - h_rate[4]*xlamda[2] + h_ratelo[0]; - v[i][1] += h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1]; - v[i][2] += h_rate[2]*xlamda[2] + h_ratelo[2]; - } - } + srd_bin_temp *= tfactor; // rescale any too-large velocities @@ -1030,9 +1075,9 @@ void FixSRD::vbin_pack(BinAve *vbin, int n, int *list, double *buf) for (int i = 0; i < n; i++) { j = list[i]; buf[m++] = vbin[j].n; - buf[m++] = vbin[j].vave[0]; - buf[m++] = vbin[j].vave[1]; - buf[m++] = vbin[j].vave[2]; + buf[m++] = vbin[j].vsum[0]; + buf[m++] = vbin[j].vsum[1]; + buf[m++] = vbin[j].vsum[2]; buf[m++] = vbin[j].random; } } @@ -1048,9 +1093,9 @@ void FixSRD::vbin_unpack(double *buf, BinAve *vbin, int n, int *list) for (int i = 0; i < n; i++) { j = list[i]; vbin[j].n += static_cast (buf[m++]); - vbin[j].vave[0] += buf[m++]; - vbin[j].vave[1] += buf[m++]; - vbin[j].vave[2] += buf[m++]; + vbin[j].vsum[0] += buf[m++]; + vbin[j].vsum[1] += buf[m++]; + vbin[j].vsum[2] += buf[m++]; vbin[j].random += buf[m++]; } } @@ -1063,7 +1108,7 @@ void FixSRD::vbin_unpack(double *buf, BinAve *vbin, int n, int *list) void FixSRD::collisions_single() { - int i,j,k,m,type,mbig,ibin,ibounce,inside,collide_flag; + int i,j,k,m,type,nbig,ibin,ibounce,inside,collide_flag,lineside; double dt,t_remain; double norm[3],xscoll[3],xbcoll[3],vsnew[3]; Big *big; @@ -1095,11 +1140,11 @@ void FixSRD::collisions_single() dt = dt_big; while (collide_flag) { - mbig = nbinbig[ibin]; - if (ibounce == 0) ncheck += mbig; + nbig = nbinbig[ibin]; + if (ibounce == 0) ncheck += nbig; collide_flag = 0; - for (m = 0; m < mbig; m++) { + for (m = 0; m < nbig; m++) { k = binbig[ibin][m]; big = &biglist[k]; j = big->index; @@ -1159,17 +1204,11 @@ void FixSRD::collisions_single() } if (collidestyle == SLIP) { - if (type == SPHERE) - slip_sphere(v[i],v[j],norm,vsnew); - else if (type == ELLIPSOID) - slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - slip_wall(v[i],j,norm,vsnew); + if (type != WALL) slip(v[i],v[j],x[j],big,xscoll,norm,vsnew); + else slip_wall(v[i],j,norm,vsnew); } else { - if (type != WALL) - noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - noslip_wall(v[i],j,xscoll,norm,vsnew); + if (type != WALL) noslip(v[i],v[j],x[j],big,-1, xscoll,norm,vsnew); + else noslip(v[i],NULL,x[j],big,j,xscoll,norm,vsnew); } if (dimension == 2) vsnew[2] = 0.0; @@ -1220,7 +1259,7 @@ void FixSRD::collisions_single() void FixSRD::collisions_multi() { - int i,j,k,m,type,mbig,ibin,ibounce,inside,jfirst,typefirst; + int i,j,k,m,type,nbig,ibin,ibounce,inside,jfirst,typefirst,jlast; double dt,t_remain,t_first; double norm[3],xscoll[3],xbcoll[3],vsnew[3]; double normfirst[3],xscollfirst[3],xbcollfirst[3]; @@ -1249,22 +1288,31 @@ void FixSRD::collisions_multi() if (nbinbig[ibin] == 0) continue; ibounce = 0; + jlast = -1; dt = dt_big; while (1) { - mbig = nbinbig[ibin]; - if (ibounce == 0) ncheck += mbig; + nbig = nbinbig[ibin]; + if (ibounce == 0) ncheck += nbig; t_first = 0.0; - for (m = 0; m < mbig; m++) { + for (m = 0; m < nbig; m++) { k = binbig[ibin][m]; big = &biglist[k]; j = big->index; + if (j == jlast) continue; type = big->type; - if (type == SPHERE) inside = inside_sphere(x[i],x[j],big); - else if (type == ELLIPSOID) inside = inside_ellipsoid(x[i],x[j],big); - else inside = inside_wall(x[i],j); + if (type == SPHERE) + inside = inside_sphere(x[i],x[j],big); + else if (type == ELLIPSOID) + inside = inside_ellipsoid(x[i],x[j],big); + else if (type == LINE) + inside = inside_line(x[i],x[j],v[i],v[j],big,dt); + else if (type == TRIANGLE) + inside = inside_tri(x[i],x[j],v[i],v[j],big,dt); + else + inside = inside_wall(x[i],j); if (inside) { if (type == SPHERE) @@ -1273,6 +1321,12 @@ void FixSRD::collisions_multi() else if (type == ELLIPSOID) t_remain = collision_ellipsoid_exact(x[i],x[j],v[i],v[j],big, xscoll,xbcoll,norm); + else if (type == LINE) + t_remain = collision_line_exact(x[i],x[j],v[i],v[j],big,dt, + xscoll,xbcoll,norm); + else if (type == TRIANGLE) + t_remain = collision_tri_exact(x[i],x[j],v[i],v[j],big,dt, + xscoll,xbcoll,norm); else t_remain = collision_wall_exact(x[i],j,v[i],xscoll,xbcoll,norm); @@ -1316,7 +1370,7 @@ void FixSRD::collisions_multi() } if (t_first == 0.0) break; - j = jfirst; + j = jlast = jfirst; type = typefirst; xscoll[0] = xscollfirst[0]; xscoll[1] = xscollfirst[1]; @@ -1329,17 +1383,11 @@ void FixSRD::collisions_multi() norm[2] = normfirst[2]; if (collidestyle == SLIP) { - if (type == SPHERE) - slip_sphere(v[i],v[j],norm,vsnew); - else if (type == ELLIPSOID) - slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - slip_wall(v[i],j,norm,vsnew); + if (type != WALL) slip(v[i],v[j],x[j],big,xscoll,norm,vsnew); + else slip_wall(v[i],j,norm,vsnew); } else { - if (type != WALL) - noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew); - else - noslip_wall(v[i],j,xscoll,norm,vsnew); + if (type != WALL) noslip(v[i],v[j],x[j],big,-1,xscoll,norm,vsnew); + else noslip(v[i],NULL,x[j],big,j,xscoll,norm,vsnew); } if (dimension == 2) vsnew[2] = 0.0; @@ -1418,6 +1466,276 @@ int FixSRD::inside_ellipsoid(double *xs, double *xb, Big *big) return 0; } +/* ---------------------------------------------------------------------- + check if SRD particle S is inside line big particle B + collision only possible if: + S starts on positive side of infinite line, + which means it will collide with outside of rigid body made of lines + since line segments have outward normals, + when vector from first to last point is crossed with +z axis + S ends on negative side of infinite line + unlike most other inside() routines, then calculate exact collision: + solve for collision pt along infinite line + collision if pt is within endpoints of B +------------------------------------------------------------------------- */ + +int FixSRD::inside_line(double *xs, double *xb, double *vs, double *vb, + Big *big, double dt_step) +{ + double pmc0[2],pmc1[2],n0[2],n1[2]; + double n1_n0[2],pmc1_pmc0[2]; + + // 1 and 2 = start and end of timestep + // pmc = P - C, where P = position of S, C = position of B + // n = normal to line = [-sin(theta),cos(theta)], theta = orientation of B + // (P-C) dot N = side of line that S is on + // side0 = -1,0,1 for which side of line B that S is on at start of step + // side1 = -1,0,1 for which side of line B that S is on at end of step + + xs1[0] = xs[0]; + xs1[1] = xs[1]; + xb1[0] = xb[0]; + xb1[1] = xb[1]; + + xs0[0] = xs1[0] - dt_step*vs[0]; + xs0[1] = xs1[1] - dt_step*vs[1]; + xb0[0] = xb1[0] - dt_step*vb[0]; + xb0[1] = xb1[1] - dt_step*vb[1]; + + theta1 = big->theta; + theta0 = theta1 - dt_step*big->omega[2]; + + pmc0[0] = xs0[0] - xb0[0]; + pmc0[1] = xs0[1] - xb0[1]; + n0[0] = sin(theta0); + n0[1] = -cos(theta0); + + pmc1[0] = xs1[0] - xb1[0]; + pmc1[1] = xs1[1] - xb1[1]; + n1[0] = sin(theta1); + n1[1] = -cos(theta1); + + double side0 = pmc0[0]*n0[0] + pmc0[1]*n0[1]; + double side1 = pmc1[0]*n1[0] + pmc1[1]*n1[1]; + + if (side0 <= 0.0 || side1 >= 0.0) return 0; + + // solve for time t (0 to 1) at which moving particle + // crosses infinite moving/rotating line + + // Newton-Raphson solve of full non-linear parametric equation + + tfraction = newton_raphson(0.0,1.0); + + // quadratic equation solve of approximate parametric equation + + /* + n1_n0[0] = n1[0]-n0[0]; n1_n0[1] = n1[1]-n0[1]; + pmc1_pmc0[0] = pmc1[0]-pmc0[0]; pmc1_pmc0[1] = pmc1[1]-pmc0[1]; + + double a = pmc1_pmc0[0]*n1_n0[0] + pmc1_pmc0[1]*n1_n0[1]; + double b = pmc1_pmc0[0]*n0[0] + pmc1_pmc0[1]*n0[1] + + n1_n0[0]*pmc0[0] + n1_n0[1]*pmc0[1]; + double c = pmc0[0]*n0[0] + pmc0[1]*n0[1]; + + if (a == 0.0) { + double dot0 = pmc0[0]*n0[0] + pmc0[1]*n0[1]; + double dot1 = pmc1[0]*n0[0] + pmc1[1]*n0[1]; + double root = -dot0 / (dot1 - dot0); + //printf("Linear root: %g %g\n",root,tfraction); + tfraction = root; + + } else { + + double term = sqrt(b*b - 4.0*a*c); + double root1 = (-b + term) / (2.0*a); + double root2 = (-b - term) / (2.0*a); + + //printf("ABC vecs: %g %g: %g %g\n", + // pmc1_pmc0[0],pmc1_pmc0[1],n1_n0[0],n1_n0[1]); + //printf("ABC vecs: %g %g: %g %g: %g %g %g\n", + // n0[0],n0[1],n1[0],n1[1],theta0,theta1,big->omega[2]); + //printf("ABC root: %g %g %g: %g %g %g\n",a,b,c,root1,root2,tfraction); + + if (0.0 <= root1 && root1 <= 1.0) tfraction = root1; + else if (0.0 <= root2 && root2 <= 1.0) tfraction = root2; + else error->one(FLERR,"Bad quadratic solve for particle/line collision"); + } + */ + + // check if collision pt is within line segment at collision time + + xsc[0] = xs0[0] + tfraction*(xs1[0]-xs0[0]); + xsc[1] = xs0[1] + tfraction*(xs1[1]-xs0[1]); + xbc[0] = xb0[0] + tfraction*(xb1[0]-xb0[0]); + xbc[1] = xb0[1] + tfraction*(xb1[1]-xb0[1]); + double delx = xsc[0] - xbc[0]; + double dely = xsc[1] - xbc[1]; + double rsq = delx*delx + dely*dely; + if (rsq > 0.25*big->length*big->length) return 0; + + //nbc[0] = n0[0] + tfraction*(n1[0]-n0[0]); + //nbc[1] = n0[1] + tfraction*(n1[1]-n0[1]); + + nbc[0] = sin(theta0 + tfraction*(theta1-theta0)); + nbc[1] = -cos(theta0 + tfraction*(theta1-theta0)); + + return 1; +} + +/* ---------------------------------------------------------------------- + check if SRD particle S is inside triangle big particle B + collision only possible if: + S starts on positive side of triangle plane, + which means it will collide with outside of rigid body made of tris + since triangles have outward normals, + S ends on negative side of triangle plane + unlike most other inside() routines, then calculate exact collision: + solve for collision pt on triangle plane + collision if pt is inside triangle B +------------------------------------------------------------------------- */ + +int FixSRD::inside_tri(double *xs, double *xb, double *vs, double *vb, + Big *big, double dt_step) +{ + double pmc0[3],pmc1[3],n0[3]; + double n1_n0[3],pmc1_pmc0[3]; + double excoll[3],eycoll[3],ezcoll[3]; + double dc1[3],dc2[3],dc3[3]; + double c1[3],c2[3],c3[3]; + double c2mc1[3],c3mc2[3],c1mc3[3]; + double pvec[3],xproduct[3]; + + // 1 and 2 = start and end of timestep + // pmc = P - C, where P = position of S, C = position of B + // n = normal to triangle + // (P-C) dot N = side of tri that S is on + // side0 = -1,0,1 for which side of tri B that S is on at start of step + // side1 = -1,0,1 for which side of tri B that S is on at end of step + + double *omega = big->omega; + double *n1 = big->norm; + + n0[0] = n1[0] - dt_step*(omega[1]*n1[2] - omega[2]*n1[1]); + n0[1] = n1[1] - dt_step*(omega[2]*n1[0] - omega[0]*n1[2]); + n0[2] = n1[2] - dt_step*(omega[0]*n1[1] - omega[1]*n1[0]); + + pmc0[0] = xs[0] - dt_step*vs[0] - xb[0] + dt_step*vb[0]; + pmc0[1] = xs[1] - dt_step*vs[1] - xb[1] + dt_step*vb[1]; + pmc0[2] = xs[2] - dt_step*vs[2] - xb[2] + dt_step*vb[2]; + pmc1[0] = xs[0] - xb[0]; + pmc1[1] = xs[1] - xb[1]; + pmc1[2] = xs[2] - xb[2]; + + double side0 = MathExtra::dot3(pmc0,n0); + double side1 = MathExtra::dot3(pmc1,n1); + + if (side0 <= 0.0 || side1 >= 0.0) return 0; + + // solve for time t (0 to 1) at which moving particle + // crosses moving/rotating tri + // quadratic equation solve of approximate parametric equation + + n1_n0[0] = n1[0]-n0[0]; + n1_n0[1] = n1[1]-n0[1]; + n1_n0[2] = n1[2]-n0[2]; + pmc1_pmc0[0] = pmc1[0]-pmc0[0]; + pmc1_pmc0[1] = pmc1[1]-pmc0[1]; + pmc1_pmc0[2] = pmc1[2]-pmc0[2]; + + double a = MathExtra::dot3(pmc1_pmc0,n1_n0); + double b = MathExtra::dot3(pmc1_pmc0,n0) + MathExtra::dot3(n1_n0,pmc0); + double c = MathExtra::dot3(pmc0,n0); + + if (a == 0.0) { + double dot0 = MathExtra::dot3(pmc0,n0); + double dot1 = MathExtra::dot3(pmc1,n0); + double root = -dot0 / (dot1 - dot0); + tfraction = root; + } else { + double term = sqrt(b*b - 4.0*a*c); + double root1 = (-b + term) / (2.0*a); + double root2 = (-b - term) / (2.0*a); + if (0.0 <= root1 && root1 <= 1.0) tfraction = root1; + else if (0.0 <= root2 && root2 <= 1.0) tfraction = root2; + else error->one(FLERR,"Bad quadratic solve for particle/tri collision"); + } + + // calculate position/orientation of S and B at collision time + // dt = time previous to now at which collision occurs + // point = S position in plane of triangle at collision time + // Excoll,Eycoll,Ezcoll = orientation of tri at collision time + // c1,c2,c3 = corner points of triangle at collision time + // nbc = normal to plane of triangle at collision time + + AtomVecTri::Bonus *tbonus; + tbonus = avec_tri->bonus; + + double *ex = big->ex; + double *ey = big->ey; + double *ez = big->ez; + int index = atom->tri[big->index]; + double *c1body = tbonus[index].c1; + double *c2body = tbonus[index].c2; + double *c3body = tbonus[index].c3; + + double dt = (1.0-tfraction)*dt_step; + + xsc[0] = xs[0] - dt*vs[0]; + xsc[1] = xs[1] - dt*vs[1]; + xsc[2] = xs[2] - dt*vs[2]; + xbc[0] = xb[0] - dt*vb[0]; + xbc[1] = xb[1] - dt*vb[1]; + xbc[2] = xb[2] - dt*vb[2]; + + excoll[0] = ex[0] - dt*(omega[1]*ex[2] - omega[2]*ex[1]); + excoll[1] = ex[1] - dt*(omega[2]*ex[0] - omega[0]*ex[2]); + excoll[2] = ex[2] - dt*(omega[0]*ex[1] - omega[1]*ex[0]); + + eycoll[0] = ey[0] - dt*(omega[1]*ey[2] - omega[2]*ey[1]); + eycoll[1] = ey[1] - dt*(omega[2]*ey[0] - omega[0]*ey[2]); + eycoll[2] = ey[2] - dt*(omega[0]*ey[1] - omega[1]*ey[0]); + + ezcoll[0] = ez[0] - dt*(omega[1]*ez[2] - omega[2]*ez[1]); + ezcoll[1] = ez[1] - dt*(omega[2]*ez[0] - omega[0]*ez[2]); + ezcoll[2] = ez[2] - dt*(omega[0]*ez[1] - omega[1]*ez[0]); + + MathExtra::matvec(excoll,eycoll,ezcoll,c1body,dc1); + MathExtra::matvec(excoll,eycoll,ezcoll,c2body,dc2); + MathExtra::matvec(excoll,eycoll,ezcoll,c3body,dc3); + + MathExtra::add3(xbc,dc1,c1); + MathExtra::add3(xbc,dc2,c2); + MathExtra::add3(xbc,dc3,c3); + + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c2,c3mc2); + MathExtra::sub3(c1,c3,c1mc3); + + MathExtra::cross3(c2mc1,c3mc2,nbc); + MathExtra::norm3(nbc); + + // check if collision pt is within triangle + // pvec = vector from tri vertex to intersection point + // xproduct = cross product of edge vec with pvec + // if dot product of xproduct with nbc < 0.0 for any of 3 edges, + // intersection point is outside tri + + MathExtra::sub3(xsc,c1,pvec); + MathExtra::cross3(c2mc1,pvec,xproduct); + if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0; + + MathExtra::sub3(xsc,c2,pvec); + MathExtra::cross3(c3mc2,pvec,xproduct); + if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0; + + MathExtra::sub3(xsc,c3,pvec); + MathExtra::cross3(c1mc3,pvec,xproduct); + if (MathExtra::dot3(xproduct,nbc) < 0.0) return 0; + + return 1; +} + /* ---------------------------------------------------------------------- check if SRD particle S is inside wall IWALL ------------------------------------------------------------------------- */ @@ -1449,7 +1767,7 @@ double FixSRD::collision_sphere_exact(double *xs, double *xb, double vs_dot_vs,vb_dot_vb,vs_dot_vb; double vs_dot_xb,vb_dot_xs,vs_dot_xs,vb_dot_xb; double xs_dot_xs,xb_dot_xb,xs_dot_xb; - double a,b,c,scale,dt; + double a,b,c,scale; vs_dot_vs = vs[0]*vs[0] + vs[1]*vs[1] + vs[2]*vs[2]; vb_dot_vb = vb[0]*vb[0] + vb[1]*vb[1] + vb[2]*vb[2]; @@ -1468,7 +1786,7 @@ double FixSRD::collision_sphere_exact(double *xs, double *xb, b = 2.0 * (vs_dot_xb + vb_dot_xs - vs_dot_xs - vb_dot_xb); c = xs_dot_xs + xb_dot_xb - 2.0*xs_dot_xb - big->radsq; - dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); + double dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); xscoll[0] = xs[0] - dt*vs[0]; xscoll[1] = xs[1] - dt*vs[1]; @@ -1539,7 +1857,7 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, double vs_vb[3],xs_xb[3],omega_ex[3],omega_ey[3],omega_ez[3]; double excoll[3],eycoll[3],ezcoll[3],delta[3],xbody[3],nbody[3]; double ax,bx,cx,ay,by,cy,az,bz,cz; - double a,b,c,dt,scale; + double a,b,c,scale; double *omega = big->omega; double *ex = big->ex; @@ -1549,17 +1867,9 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, vs_vb[0] = vs[0]-vb[0]; vs_vb[1] = vs[1]-vb[1]; vs_vb[2] = vs[2]-vb[2]; xs_xb[0] = xs[0]-xb[0]; xs_xb[1] = xs[1]-xb[1]; xs_xb[2] = xs[2]-xb[2]; - omega_ex[0] = omega[1]*ex[2] - omega[2]*ex[1]; - omega_ex[1] = omega[2]*ex[0] - omega[0]*ex[2]; - omega_ex[2] = omega[0]*ex[1] - omega[1]*ex[0]; - - omega_ey[0] = omega[1]*ey[2] - omega[2]*ey[1]; - omega_ey[1] = omega[2]*ey[0] - omega[0]*ey[2]; - omega_ey[2] = omega[0]*ey[1] - omega[1]*ey[0]; - - omega_ez[0] = omega[1]*ez[2] - omega[2]*ez[1]; - omega_ez[1] = omega[2]*ez[0] - omega[0]*ez[2]; - omega_ez[2] = omega[0]*ez[1] - omega[1]*ez[0]; + MathExtra::cross3(omega,ex,omega_ex); + MathExtra::cross3(omega,ey,omega_ey); + MathExtra::cross3(omega,ez,omega_ez); ax = vs_vb[0]*omega_ex[0] + vs_vb[1]*omega_ex[1] + vs_vb[2]*omega_ex[2]; bx = -(vs_vb[0]*ex[0] + vs_vb[1]*ex[1] + vs_vb[2]*ex[2]); @@ -1584,7 +1894,7 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, c = cx*cx*big->aradsqinv + cy*cy*big->bradsqinv + cz*cz*big->cradsqinv - 1.0; - dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); + double dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a); xscoll[0] = xs[0] - dt*vs[0]; xscoll[1] = xs[1] - dt*vs[1]; @@ -1600,37 +1910,27 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, // norm = normal in space frame // only worry about normalizing final norm vector - excoll[0] = ex[0] - dt * (omega[1]*ex[2] - omega[2]*ex[1]); - excoll[1] = ex[1] - dt * (omega[2]*ex[0] - omega[0]*ex[2]); - excoll[2] = ex[2] - dt * (omega[0]*ex[1] - omega[1]*ex[0]); + excoll[0] = ex[0] - dt*(omega[1]*ex[2] - omega[2]*ex[1]); + excoll[1] = ex[1] - dt*(omega[2]*ex[0] - omega[0]*ex[2]); + excoll[2] = ex[2] - dt*(omega[0]*ex[1] - omega[1]*ex[0]); - eycoll[0] = ey[0] - dt * (omega[1]*ey[2] - omega[2]*ey[1]); - eycoll[1] = ey[1] - dt * (omega[2]*ey[0] - omega[0]*ey[2]); - eycoll[2] = ey[2] - dt * (omega[0]*ey[1] - omega[1]*ey[0]); + eycoll[0] = ey[0] - dt*(omega[1]*ey[2] - omega[2]*ey[1]); + eycoll[1] = ey[1] - dt*(omega[2]*ey[0] - omega[0]*ey[2]); + eycoll[2] = ey[2] - dt*(omega[0]*ey[1] - omega[1]*ey[0]); - ezcoll[0] = ez[0] - dt * (omega[1]*ez[2] - omega[2]*ez[1]); - ezcoll[1] = ez[1] - dt * (omega[2]*ez[0] - omega[0]*ez[2]); - ezcoll[2] = ez[2] - dt * (omega[0]*ez[1] - omega[1]*ez[0]); + ezcoll[0] = ez[0] - dt*(omega[1]*ez[2] - omega[2]*ez[1]); + ezcoll[1] = ez[1] - dt*(omega[2]*ez[0] - omega[0]*ez[2]); + ezcoll[2] = ez[2] - dt*(omega[0]*ez[1] - omega[1]*ez[0]); - delta[0] = xscoll[0] - xbcoll[0]; - delta[1] = xscoll[1] - xbcoll[1]; - delta[2] = xscoll[2] - xbcoll[2]; - - xbody[0] = delta[0]*excoll[0] + delta[1]*excoll[1] + delta[2]*excoll[2]; - xbody[1] = delta[0]*eycoll[0] + delta[1]*eycoll[1] + delta[2]*eycoll[2]; - xbody[2] = delta[0]*ezcoll[0] + delta[1]*ezcoll[1] + delta[2]*ezcoll[2]; + MathExtra::sub3(xscoll,xbcoll,delta); + MathExtra::transpose_matvec(excoll,eycoll,ezcoll,delta,xbody); nbody[0] = xbody[0]*big->aradsqinv; nbody[1] = xbody[1]*big->bradsqinv; nbody[2] = xbody[2]*big->cradsqinv; - norm[0] = excoll[0]*nbody[0] + eycoll[0]*nbody[1] + ezcoll[0]*nbody[2]; - norm[1] = excoll[1]*nbody[0] + eycoll[1]*nbody[1] + ezcoll[1]*nbody[2]; - norm[2] = excoll[2]*nbody[0] + eycoll[2]*nbody[1] + ezcoll[2]*nbody[2]; - scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]); - norm[0] *= scale; - norm[1] *= scale; - norm[2] *= scale; + MathExtra::matvec(excoll,eycoll,ezcoll,nbody,norm); + MathExtra::norm3(norm); return dt; } @@ -1638,6 +1938,10 @@ double FixSRD::collision_ellipsoid_exact(double *xs, double *xb, /* ---------------------------------------------------------------------- collision of SRD particle S with surface of ellipsoidal big particle B inexact because just push SRD to surface of big particle at end of step + time of collision = end of step + xscoll = collision pt = position of SRD at time of collision + xbcoll = xb = position of big particle at time of collision + norm = surface normal of collision pt at time of collision ------------------------------------------------------------------------- */ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, @@ -1646,22 +1950,18 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, double *norm) { double xs_xb[3],delta[3],xbody[3],nbody[3]; - double x,y,z,scale; double *ex = big->ex; double *ey = big->ey; double *ez = big->ez; - xs_xb[0] = xs[0] - xb[0]; - xs_xb[1] = xs[1] - xb[1]; - xs_xb[2] = xs[2] - xb[2]; + MathExtra::sub3(xs,xb,xs_xb); + double x = MathExtra::dot3(xs_xb,ex); + double y = MathExtra::dot3(xs_xb,ey); + double z = MathExtra::dot3(xs_xb,ez); - x = xs_xb[0]*ex[0] + xs_xb[1]*ex[1] + xs_xb[2]*ex[2]; - y = xs_xb[0]*ey[0] + xs_xb[1]*ey[1] + xs_xb[2]*ey[2]; - z = xs_xb[0]*ez[0] + xs_xb[1]*ez[1] + xs_xb[2]*ez[2]; - - scale = 1.0/sqrt(x*x*big->aradsqinv + y*y*big->bradsqinv + - z*z*big->cradsqinv); + double scale = 1.0/sqrt(x*x*big->aradsqinv + y*y*big->bradsqinv + + z*z*big->cradsqinv); x *= scale; y *= scale; z *= scale; @@ -1679,25 +1979,73 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, // norm = normal in space frame // only worry about normalizing final norm vector - delta[0] = xscoll[0] - xbcoll[0]; - delta[1] = xscoll[1] - xbcoll[1]; - delta[2] = xscoll[2] - xbcoll[2]; - - xbody[0] = delta[0]*ex[0] + delta[1]*ex[1] + delta[2]*ex[2]; - xbody[1] = delta[0]*ey[0] + delta[1]*ey[1] + delta[2]*ey[2]; - xbody[2] = delta[0]*ez[0] + delta[1]*ez[1] + delta[2]*ez[2]; + MathExtra::sub3(xscoll,xbcoll,delta); + MathExtra::transpose_matvec(ex,ey,ez,delta,xbody); nbody[0] = xbody[0]*big->aradsqinv; nbody[1] = xbody[1]*big->bradsqinv; nbody[2] = xbody[2]*big->cradsqinv; - norm[0] = ex[0]*nbody[0] + ey[0]*nbody[1] + ez[0]*nbody[2]; - norm[1] = ex[1]*nbody[0] + ey[1]*nbody[1] + ez[1]*nbody[2]; - norm[2] = ex[2]*nbody[0] + ey[2]*nbody[1] + ez[2]*nbody[2]; - scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]); - norm[0] *= scale; - norm[1] *= scale; - norm[2] *= scale; + MathExtra::matvec(ex,ey,ez,nbody,norm); + MathExtra::norm3(norm); +} + +/* ---------------------------------------------------------------------- + collision of SRD particle S with surface of line big particle B + exact because compute time of collision + dt = time previous to now at which collision occurs + xscoll = collision pt = position of SRD at time of collision + xbcoll = position of big particle at time of collision + norm = surface normal of collision pt at time of collision +------------------------------------------------------------------------- */ + +double FixSRD::collision_line_exact(double *xs, double *xb, + double *vs, double *vb, Big *big, + double dt_step, + double *xscoll, double *xbcoll, + double *norm) +{ + xscoll[0] = xsc[0]; + xscoll[1] = xsc[1]; + xscoll[2] = 0.0; + xbcoll[0] = xbc[0]; + xbcoll[1] = xbc[1]; + xbcoll[2] = 0.0; + + norm[0] = nbc[0]; + norm[1] = nbc[1]; + norm[2] = 0.0; + + return (1.0-tfraction)*dt_step; +} + +/* ---------------------------------------------------------------------- + collision of SRD particle S with surface of triangle big particle B + exact because compute time of collision + dt = time previous to now at which collision occurs + xscoll = collision pt = position of SRD at time of collision + xbcoll = position of big particle at time of collision + norm = surface normal of collision pt at time of collision +------------------------------------------------------------------------- */ + +double FixSRD::collision_tri_exact(double *xs, double *xb, + double *vs, double *vb, Big *big, + double dt_step, + double *xscoll, double *xbcoll, + double *norm) +{ + xscoll[0] = xsc[0]; + xscoll[1] = xsc[1]; + xscoll[2] = xsc[2]; + xbcoll[0] = xbc[0]; + xbcoll[1] = xbc[1]; + xbcoll[2] = xbc[2]; + + norm[0] = nbc[0]; + norm[1] = nbc[1]; + norm[2] = nbc[2]; + + return (1.0-tfraction)*dt_step; } /* ---------------------------------------------------------------------- @@ -1705,6 +2053,7 @@ void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb, exact because compute time of collision dt = time previous to now at which collision occurs xscoll = collision pt = position of SRD at time of collision + xbcoll = position of wall at time of collision norm = surface normal of collision pt at time of collision ------------------------------------------------------------------------- */ @@ -1735,6 +2084,7 @@ double FixSRD::collision_wall_exact(double *xs, int iwall, double *vs, inexact because just push SRD to surface of wall at end of step time of collision = end of step xscoll = collision pt = position of SRD at time of collision + xbcoll = position of wall at time of collision norm = surface normal of collision pt at time of collision ------------------------------------------------------------------------- */ @@ -1758,54 +2108,18 @@ void FixSRD::collision_wall_inexact(double *xs, int iwall, double *xscoll, } /* ---------------------------------------------------------------------- - SLIP collision with sphere - vs = velocity of SRD, vb = velocity of BIG - norm = unit normal from surface of BIG at collision pt - v of BIG particle in direction of surf normal is added to v of SRD - return vsnew of SRD -------------------------------------------------------------------------- */ - -void FixSRD::slip_sphere(double *vs, double *vb, double *norm, double *vsnew) -{ - double r1,r2,vnmag,vs_dot_n,vsurf_dot_n; - double tangent[3]; - - while (1) { - r1 = sigma * random->gaussian(); - r2 = sigma * random->gaussian(); - vnmag = sqrt(r1*r1 + r2*r2); - if (vnmag*vnmag <= vmaxsq) break; - } - - vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2]; - - tangent[0] = vs[0] - vs_dot_n*norm[0]; - tangent[1] = vs[1] - vs_dot_n*norm[1]; - tangent[2] = vs[2] - vs_dot_n*norm[2]; - - // vsurf = velocity of collision pt = translation/rotation of BIG particle - // for sphere, only vb (translation) can contribute in normal direction - - vsurf_dot_n = vb[0]*norm[0] + vb[1]*norm[1] + vb[2]*norm[2]; - - vsnew[0] = (vnmag+vsurf_dot_n)*norm[0] + tangent[0]; - vsnew[1] = (vnmag+vsurf_dot_n)*norm[1] + tangent[1]; - vsnew[2] = (vnmag+vsurf_dot_n)*norm[2] + tangent[2]; -} - -/* ---------------------------------------------------------------------- - SLIP collision with ellipsoid + SLIP collision with BIG particle with omega vs = velocity of SRD, vb = velocity of BIG xb = position of BIG, omega = rotation of BIG xsurf = collision pt on surf of BIG norm = unit normal from surface of BIG at collision pt v of BIG particle in direction of surf normal is added to v of SRD - includes component due to rotation of ellipsoid + includes component due to rotation of BIG return vsnew of SRD ------------------------------------------------------------------------- */ -void FixSRD::slip_ellipsoid(double *vs, double *vb, double *xb, Big *big, - double *xsurf, double *norm, double *vsnew) +void FixSRD::slip(double *vs, double *vb, double *xb, Big *big, + double *xsurf, double *norm, double *vsnew) { double r1,r2,vnmag,vs_dot_n,vsurf_dot_n; double tangent[3],vsurf[3]; @@ -1825,6 +2139,8 @@ void FixSRD::slip_ellipsoid(double *vs, double *vb, double *xb, Big *big, tangent[2] = vs[2] - vs_dot_n*norm[2]; // vsurf = velocity of collision pt = translation/rotation of BIG particle + // NOTE: for sphere could just use vsurf = vb, since w x (xsurf-xb) + // is orthogonal to norm and thus doesn't contribute to vsurf_dot_n vsurf[0] = vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]); vsurf[1] = vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]); @@ -1885,7 +2201,7 @@ void FixSRD::slip_wall(double *vs, int iwall, double *norm, double *vsnew) } /* ---------------------------------------------------------------------- - NO-SLIP collision with sphere or ellipsoid + NO-SLIP collision with BIG particle including WALL vs = velocity of SRD, vb = velocity of BIG xb = position of BIG, omega = rotation of BIG xsurf = collision pt on surf of BIG @@ -1895,12 +2211,11 @@ void FixSRD::slip_wall(double *vs, int iwall, double *norm, double *vsnew) return vsnew of SRD ------------------------------------------------------------------------- */ -void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big, +void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big, int iwall, double *xsurf, double *norm, double *vsnew) { double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2; double tangent1[3],tangent2[3]; - double *omega = big->omega; vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2]; @@ -1930,60 +2245,20 @@ void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big, vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1]; vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2]; - // add in velocity of collision pt = translation/rotation of BIG particle + // add in velocity of collision pt + // for WALL: velocity of wall in one dim + // else: translation/rotation of BIG particle - vsnew[0] += vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]); - vsnew[1] += vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]); - vsnew[2] += vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]); -} + if (big->type == WALL) { + int dim = wallwhich[iwall] / 2; + vsnew[dim] += vwall[iwall]; -/* ---------------------------------------------------------------------- - NO-SLIP collision with wall IWALL - vs = velocity of SRD - xsurf = collision pt on surf of WALL - norm = unit normal from WALL at collision pt - v of collision pt is added to v of SRD - return vsnew of SRD -------------------------------------------------------------------------- */ - -void FixSRD::noslip_wall(double *vs, int iwall, - double *xsurf, double *norm, double *vsnew) -{ - double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2; - double tangent1[3],tangent2[3]; - - vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2]; - - tangent1[0] = vs[0] - vs_dot_n*norm[0]; - tangent1[1] = vs[1] - vs_dot_n*norm[1]; - tangent1[2] = vs[2] - vs_dot_n*norm[2]; - scale = 1.0/sqrt(tangent1[0]*tangent1[0] + tangent1[1]*tangent1[1] + - tangent1[2]*tangent1[2]); - tangent1[0] *= scale; - tangent1[1] *= scale; - tangent1[2] *= scale; - - tangent2[0] = norm[1]*tangent1[2] - norm[2]*tangent1[1]; - tangent2[1] = norm[2]*tangent1[0] - norm[0]*tangent1[2]; - tangent2[2] = norm[0]*tangent1[1] - norm[1]*tangent1[0]; - - while (1) { - r1 = sigma * random->gaussian(); - r2 = sigma * random->gaussian(); - vnmag = sqrt(r1*r1 + r2*r2); - vtmag1 = sigma * random->gaussian(); - vtmag2 = sigma * random->gaussian(); - if (vnmag*vnmag + vtmag1*vtmag1 + vtmag2*vtmag2 <= vmaxsq) break; + } else { + double *omega = big->omega; + vsnew[0] += vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]); + vsnew[1] += vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]); + vsnew[2] += vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]); } - - vsnew[0] = vnmag*norm[0] + vtmag1*tangent1[0] + vtmag2*tangent2[0]; - vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1]; - vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2]; - - // add in velocity of collision pt = velocity of wall - - int dim = wallwhich[iwall] / 2; - vsnew[dim] += vwall[iwall]; } /* ---------------------------------------------------------------------- @@ -2025,6 +2300,7 @@ void FixSRD::force_torque(double *vsold, double *vsnew, ------------------------------------------------------------------------- */ void FixSRD::force_wall(double *vsold, double *vsnew, int iwall) + { double dpdt[3]; @@ -2087,8 +2363,6 @@ int FixSRD::update_srd(int i, double dt, double *xscoll, double *vsnew, void FixSRD::parameterize() { - double PI = 4.0*atan(1.0); - // timesteps dt_big = update->dt; @@ -2100,12 +2374,20 @@ void FixSRD::parameterize() AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double *radius = atom->radius; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; int *mask = atom->mask; int nlocal = atom->nlocal; - any_ellipsoids = 0; + int any_ellipsoids = 0; + int any_lines = 0; + int any_tris = 0; maxbigdiam = 0.0; minbigdiam = BIG; @@ -2123,6 +2405,20 @@ void FixSRD::parameterize() minbigdiam = MIN(minbigdiam,2.0*shape[0]); minbigdiam = MIN(minbigdiam,2.0*shape[1]); minbigdiam = MIN(minbigdiam,2.0*shape[2]); + } else if (line && line[i] >= 0) { + any_lines = 1; + double length = lbonus[line[i]].length; + maxbigdiam = MAX(maxbigdiam,length); + minbigdiam = MIN(minbigdiam,length); + } else if (tri && tri[i] >= 0) { + any_tris = 1; + double length1 = MathExtra::len3(tbonus[tri[i]].c1); + double length2 = MathExtra::len3(tbonus[tri[i]].c2); + double length3 = MathExtra::len3(tbonus[tri[i]].c3); + double length = MAX(length1,length2); + length = MAX(length,length3); + maxbigdiam = MAX(maxbigdiam,length); + minbigdiam = MIN(minbigdiam,length); } else error->one(FLERR,"Big particle in fix srd cannot be point particle"); } @@ -2137,10 +2433,20 @@ void FixSRD::parameterize() int itmp = any_ellipsoids; MPI_Allreduce(&itmp,&any_ellipsoids,1,MPI_INT,MPI_MAX,world); + itmp = any_lines; + MPI_Allreduce(&itmp,&any_lines,1,MPI_INT,MPI_MAX,world); + itmp = any_tris; + MPI_Allreduce(&itmp,&any_tris,1,MPI_INT,MPI_MAX,world); - // big particles are only torqued if are ellipsoids or NOSLIP collisions + if (any_lines && overlap == 0) + error->all(FLERR,"Cannot use lines with fix srd unless overlap is set"); + if (any_tris && overlap == 0) + error->all(FLERR,"Cannot use tris with fix srd unless overlap is set"); - if (any_ellipsoids == 0 && collidestyle == SLIP) torqueflag = 0; + // big particles are only torqued if ellipsoids/lines/tris or NOSLIP + + if (any_ellipsoids == 0 && any_lines == 0 && any_tris == 0 && + collidestyle == SLIP) torqueflag = 0; else torqueflag = 1; // mass of SRD particles, require monodispersity @@ -2186,28 +2492,46 @@ void FixSRD::parameterize() vmaxsq = vmax*vmax; // volbig = total volume of all big particles + // LINE/TRI particles have no volume + // incorrect if part of rigid particles, so add fudge factor with WIDTH // apply radfactor to reduce final volume double volbig = 0.0; + double WIDTH = 1.0; if (dimension == 3) { for (int i = 0; i < nlocal; i++) if (mask[i] & biggroupbit) { - if (radius && radius[i] > 0.0) - volbig += 4.0/3.0*PI*radius[i]*radius[i]*radius[i]; - else if (ellipsoid && ellipsoid[i] >= 0) { + if (radius && radius[i] > 0.0) { + double r = radfactor * radius[i]; + volbig += 4.0/3.0*MY_PI * r*r*r;; + } else if (ellipsoid && ellipsoid[i] >= 0) { double *shape = ebonus[ellipsoid[i]].shape; - volbig += 4.0/3.0*PI * shape[0]*shape[1]*shape[2]; + volbig += 4.0/3.0*MY_PI * shape[0]*shape[1]*shape[2] * + radfactor*radfactor*radfactor; + } else if (tri && tri[i] >= 0) { + double *c1 = tbonus[tri[i]].c1; + double *c2 = tbonus[tri[i]].c2; + double *c3 = tbonus[tri[i]].c3; + double c2mc1[3],c3mc1[3],cross[3]; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + MathExtra::cross3(c2mc1,c3mc1,cross); + volbig += 0.5 * MathExtra::len3(cross); } } } else { for (int i = 0; i < nlocal; i++) if (mask[i] & biggroupbit) { - if (radius && radius[i] > 0.0) - volbig += PI*radius[i]*radius[i]; - else if (ellipsoid && ellipsoid[i] >= 0) { + if (radius && radius[i] > 0.0) { + double r = radfactor * radius[i]; + volbig += MY_PI * r*r; + } else if (ellipsoid && ellipsoid[i] >= 0) { double *shape = ebonus[ellipsoid[i]].shape; - volbig += PI*shape[0]*shape[1]; + volbig += MY_PI * shape[0]*shape[1] * radfactor*radfactor; + } else if (line && line[i] >= 0) { + double length = lbonus[line[i]].length; + volbig += length * WIDTH; } } } @@ -2215,9 +2539,6 @@ void FixSRD::parameterize() tmp = volbig; MPI_Allreduce(&tmp,&volbig,1,MPI_DOUBLE,MPI_SUM,world); - if (dimension == 3) volbig *= radfactor*radfactor*radfactor; - else volbig *= radfactor*radfactor; - // particle counts bigint mbig = 0; @@ -2228,7 +2549,10 @@ void FixSRD::parameterize() mass_big = 0.0; for (int i = 0; i < nlocal; i++) - if (mask[i] & biggroupbit) mass_big += rmass[i]; + if (mask[i] & biggroupbit) { + if (rmass) mass_big += rmass[i]; + else mass_big += mass[type[i]]; + } tmp = mass_big; MPI_Allreduce(&tmp,&mass_big,1,MPI_DOUBLE,MPI_SUM,world); @@ -2369,7 +2693,8 @@ void FixSRD::parameterize() if (cubicflag == CUBIC_ERROR) error->all(FLERR,"SRD bin size for fix srd differs from user request"); if (me == 0) - error->warning(FLERR,"SRD bin size for fix srd differs from user request"); + error->warning(FLERR, + "SRD bin size for fix srd differs from user request"); } // error if lamda < 0.6 of SRD grid size and no shifting allowed @@ -2400,30 +2725,46 @@ void FixSRD::parameterize() /* ---------------------------------------------------------------------- set static parameters of each big particle, owned and ghost called each reneighboring - use radfactor in distance parameters + use radfactor in distance parameters as appropriate ------------------------------------------------------------------------- */ void FixSRD::big_static() { int i; - double rad,arad,brad,crad; - double *shape; + double rad,arad,brad,crad,length,length1,length2,length3; + double *shape,*c1,*c2,*c3; + double c2mc1[3],c3mc1[3]; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double *radius = atom->radius; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; + int *type = atom->type; double skinhalf = 0.5 * neighbor->skin; for (int k = 0; k < nbig; k++) { i = biglist[k].index; + + // sphere + // set radius and radsq and cutoff based on radius + if (radius && radius[i] > 0.0) { biglist[k].type = SPHERE; rad = radfactor*radius[i]; biglist[k].radius = rad; biglist[k].radsq = rad*rad; biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); + + // ellipsoid + // set abc radsqinv and cutoff based on max radius + } else if (ellipsoid && ellipsoid[i] >= 0) { shape = ebonus[ellipsoid[i]].shape; biglist[k].type = ELLIPSOID; @@ -2436,33 +2777,67 @@ void FixSRD::big_static() rad = MAX(arad,brad); rad = MAX(rad,crad); biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); + + // line + // set length and cutoff based on 1/2 length + + } else if (line && line[i] >= 0) { + length = lbonus[line[i]].length; + biglist[k].type = LINE; + biglist[k].length = length; + rad = 0.5*length; + biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); + + // tri + // set normbody based on c1,c2,c3 + // set cutoff based on point furthest from centroid + + } else if (tri && tri[i] >= 0) { + biglist[k].type = TRIANGLE; + c1 = tbonus[tri[i]].c1; + c2 = tbonus[tri[i]].c2; + c3 = tbonus[tri[i]].c3; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + MathExtra::cross3(c2mc1,c3mc1,biglist[k].normbody); + length1 = MathExtra::len3(c1); + length2 = MathExtra::len3(c2); + length3 = MathExtra::len3(c3); + rad = MAX(length1,length2); + rad = MAX(rad,length3); + biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf); } } } /* ---------------------------------------------------------------------- - set dynamics parameters of each big particle, owned and ghost - for ELLIPSOID, need current omega and ex,ey,ez - for SPHERE, need current omega from atom->omega or atom->angmom + set dynamic parameters of each big particle, owned and ghost called each timestep ------------------------------------------------------------------------- */ void FixSRD::big_dynamic() { int i; - double *shape,*quat; + double *shape,*quat,*inertia; + double inertiaone[3]; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **omega = atom->omega; double **angmom = atom->angmom; double *rmass = atom->rmass; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; for (int k = 0; k < nbig; k++) { i = biglist[k].index; - // sphere with omega + // sphere // set omega from atom->omega directly if (biglist[k].type == SPHERE) { @@ -2470,15 +2845,45 @@ void FixSRD::big_dynamic() biglist[k].omega[1] = omega[i][1]; biglist[k].omega[2] = omega[i][2]; - // ellipsoid with angmom - // calculate ex,ey,ez and omega from quaternion and angmom + // ellipsoid + // set ex,ey,ez from quaternion + // set omega from angmom & ex,ey,ez } else if (biglist[k].type == ELLIPSOID) { - shape = ebonus[ellipsoid[i]].shape; quat = ebonus[ellipsoid[i]].quat; - exyz_from_q(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez); - omega_from_mq(angmom[i],biglist[k].ex,biglist[k].ey,biglist[k].ez, - rmass[i],shape,biglist[k].omega); + MathExtra::q_to_exyz(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez); + shape = ebonus[ellipsoid[i]].shape; + inertiaone[0] = EINERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]); + inertiaone[1] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]); + inertiaone[2] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]); + MathExtra::angmom_to_omega(angmom[i], + biglist[k].ex,biglist[k].ey,biglist[k].ez, + inertiaone,biglist[k].omega); + + // line + // set omega from atom->omega directly + + } else if (biglist[k].type == LINE) { + biglist[k].theta = lbonus[line[i]].theta; + biglist[k].omega[0] = omega[i][0]; + biglist[k].omega[1] = omega[i][1]; + biglist[k].omega[2] = omega[i][2]; + + // tri + // set ex,ey,ez from quaternion + // set omega from angmom & ex,ey,ez + // set unit space-frame norm from body-frame norm + + } else if (biglist[k].type == TRIANGLE) { + quat = tbonus[tri[i]].quat; + MathExtra::q_to_exyz(quat,biglist[k].ex,biglist[k].ey,biglist[k].ez); + inertia = tbonus[tri[i]].inertia; + MathExtra::angmom_to_omega(angmom[i], + biglist[k].ex,biglist[k].ey,biglist[k].ez, + inertia,biglist[k].omega); + MathExtra::matvec(biglist[k].ex,biglist[k].ey,biglist[k].ez, + biglist[k].normbody,biglist[k].norm); + MathExtra::norm3(biglist[k].norm); } } } @@ -2967,10 +3372,10 @@ void FixSRD::setup_velocity_shift(int ishift, int dynamic) for (m = 0; m < nsend; m++) vbin[sendlist[m]].owner = 0; } - // if triclinic and streamflag: - // set xctr (in lamda units) for all nbins so can compute bin vstream + // if tstat and deformflag: + // set xctr for all nbins in lamda units so can later compute vstream of bin - if (triclinic && streamflag) { + if (tstat && deformflag) { m = 0; for (k = 0; k < nbinz; k++) for (j = 0; j < nbiny; j++) @@ -3182,55 +3587,6 @@ double FixSRD::bin_bin_distance(int i, int j, int k) return (delx*delx + dely*dely + delz*delz); } -/* ---------------------------------------------------------------------- - compute space-frame ex,ey,ez from current quaternion q - ex,ey,ez = space-frame coords of 1st,2nd,3rd principal axis - operation is ex = q' d q = Q d, where d is (1,0,0) = 1st axis in body frame -------------------------------------------------------------------------- */ - -void FixSRD::exyz_from_q(double *q, double *ex, double *ey, double *ez) -{ - ex[0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3]; - ex[1] = 2.0 * (q[1]*q[2] + q[0]*q[3]); - ex[2] = 2.0 * (q[1]*q[3] - q[0]*q[2]); - - ey[0] = 2.0 * (q[1]*q[2] - q[0]*q[3]); - ey[1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3]; - ey[2] = 2.0 * (q[2]*q[3] + q[0]*q[1]); - - ez[0] = 2.0 * (q[1]*q[3] + q[0]*q[2]); - ez[1] = 2.0 * (q[2]*q[3] - q[0]*q[1]); - ez[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]; -} - -/* ---------------------------------------------------------------------- - compute omega from angular momentum - w = omega = angular velocity in space frame - wbody = angular velocity in body frame - set wbody component to 0.0 if inertia component is 0.0 - otherwise body can spin easily around that axis - project space-frame angular momentum onto body axes - and divide by principal moments -------------------------------------------------------------------------- */ - -void FixSRD::omega_from_mq(double *m, double *ex, double *ey, double *ez, - double mass, double *shape, double *w) -{ - double inertia[3],wbody[3]; - - inertia[0] = 0.2*mass * (shape[1]*shape[1]+shape[2]*shape[2]); - inertia[1] = 0.2*mass * (shape[0]*shape[0]+shape[2]*shape[2]); - inertia[2] = 0.2*mass * (shape[0]*shape[0]+shape[1]*shape[1]); - - wbody[0] = (m[0]*ex[0] + m[1]*ex[1] + m[2]*ex[2]) / inertia[0]; - wbody[1] = (m[0]*ey[0] + m[1]*ey[1] + m[2]*ey[2]) / inertia[1]; - wbody[2] = (m[0]*ez[0] + m[1]*ez[1] + m[2]*ez[2]) / inertia[2]; - - w[0] = wbody[0]*ex[0] + wbody[1]*ey[0] + wbody[2]*ez[0]; - w[1] = wbody[0]*ex[1] + wbody[1]*ey[1] + wbody[2]*ez[1]; - w[2] = wbody[0]*ex[2] + wbody[1]*ey[2] + wbody[2]*ez[2]; -} - /* ---------------------------------------------------------------------- */ int FixSRD::pack_reverse_comm(int n, int first, double *buf) @@ -3365,6 +3721,90 @@ void FixSRD::velocity_stats(int groupnum) /* ---------------------------------------------------------------------- */ +double FixSRD::newton_raphson(double t1, double t2) +{ + double f1,f2,df,tlo,thi; + lineside(t1,f1,df); + if (f1 < 0.0) { + tlo = t1; + thi = t2; + } else { + thi = t1; + tlo = t2; + } + + double f; + double t = 0.5*(t1+t2); + double dtold = fabs(t2-t1); + double dt = dtold; + lineside(t,f,df); + + double temp; + for (int i = 0; i < MAXITER; i++) { + if ((((t-thi)*df - f)*((t-tlo)*df - f) > 0.0) || + (fabs(2.0*f) > fabs(dtold*df))) { + dtold = dt; + dt = 0.5 * (thi-tlo); + t = tlo + dt; + if (tlo == t) return t; + } else { + dtold = dt; + dt = f / df; + temp = t; + t -= dt; + if (temp == t) return t; + } + if (fabs(dt) < TOLERANCE) return t; + lineside(t,f,df); + if (f < 0.0) tlo = t; + else thi = t; + } + + return t; +} + +/* ---------------------------------------------------------------------- */ + +void FixSRD::lineside(double t, double &f, double &df) +{ + double p[2],c[2]; + + p[0] = xs0[0] + (xs1[0]-xs0[0])*t; + p[1] = xs0[1] + (xs1[1]-xs0[1])*t; + c[0] = xb0[0] + (xb1[0]-xb0[0])*t; + c[1] = xb0[1] + (xb1[1]-xb0[1])*t; + double dtheta = theta1 - theta0; + double theta = theta0 + dtheta*t; + double cosT = cos(theta); + double sinT = sin(theta); + + f = (p[1]-c[1]) * cosT - (p[0]-c[0]) * sinT; + df = ((xs1[1]-xs0[1]) - (xb1[1]-xb0[1]))*cosT - (p[1]-c[1])*sinT*dtheta - + ((xs1[0]-xs0[0]) - (xb1[0]-xb0[0]))*sinT - (p[0]-c[0])*cosT*dtheta; +} + +/* ---------------------------------------------------------------------- */ + +void FixSRD::triside(double t, double &f, double &df) +{ + double p[2],c[2]; + + p[0] = xs0[0] + (xs1[0]-xs0[0])*t; + p[1] = xs0[1] + (xs1[1]-xs0[1])*t; + c[0] = xb0[0] + (xb1[0]-xb0[0])*t; + c[1] = xb0[1] + (xb1[1]-xb0[1])*t; + double dtheta = theta1 - theta0; + double theta = theta0 + dtheta*t; + double cosT = cos(theta); + double sinT = sin(theta); + + f = (p[1]-c[1]) * cosT - (p[0]-c[0]) * sinT; + df = ((xs1[1]-xs0[1]) - (xb1[1]-xb0[1]))*cosT - (p[1]-c[1])*sinT*dtheta - + ((xs1[0]-xs0[0]) - (xb1[0]-xb0[0]))*sinT - (p[0]-c[0])*cosT*dtheta; +} + +/* ---------------------------------------------------------------------- */ + double FixSRD::memory_usage() { double bytes = 0.0; diff --git a/src/SRD/fix_srd.h b/src/SRD/fix_srd.h index 8552078e6d..43d9f7c2e3 100644 --- a/src/SRD/fix_srd.h +++ b/src/SRD/fix_srd.h @@ -43,9 +43,9 @@ class FixSRD : public Fix { int me,nprocs; int bigexist,biggroup,biggroupbit; int collidestyle,lamdaflag,overlap,insideflag,exactflag,maxbounceallow; - int cubicflag,shiftuser,shiftseed,shiftflag,streamflag; + int cubicflag,shiftuser,shiftseed,shiftflag,tstat; double gridsrd,gridsearch,lamda,radfactor,cubictol; - int triclinic,change_size,change_shape; + int triclinic,change_size,change_shape,deformflag; double dt_big,dt_srd; double mass_big,mass_srd; @@ -64,6 +64,8 @@ class FixSRD : public Fix { double walltrigger; class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; // for orthogonal box, these are in box units // for triclinic box, these are in lamda units @@ -92,18 +94,21 @@ class FixSRD : public Fix { struct Big { int index; // local index of particle/wall - int type; // SPHERE or ELLIPSOID or WALL + int type; // SPHERE or ELLIPSOID or LINE or TRI or WALL double radius,radsq; // radius of sphere double aradsqinv; // 3 ellipsoid radii double bradsqinv; double cradsqinv; + double length; // length of line segment + double normbody[3]; // normal of tri in body-frame double cutbinsq; // add big to bin if within this distance - double omega[3]; // current omega for sphere or ellipsoid - double ex[3],ey[3],ez[3]; // current orientation vecs for ellipsoid + double omega[3]; // current omega for sphere/ellipsoid/tri/line + double ex[3],ey[3],ez[3]; // current orientation vecs for ellipsoid/tri + double norm[3]; // current unit normal of tri in space-frame + double theta; // current orientation of line }; Big *biglist; // list of info for each owned & ghost big and wall - int any_ellipsoids; // 1 if any big particles are ellipsoids int torqueflag; // 1 if any big particle is torqued // current size of particle-based arrays @@ -123,7 +128,7 @@ class FixSRD : public Fix { int owner; // 1 if I am owner of this bin, 0 if not int n; // # of SRD particles in bin double xctr[3]; // center point of bin, only used for triclinic - double vave[3]; // sum of v components for SRD particles in bin + double vsum[3]; // sum of v components for SRD particles in bin double random; // random value if I am owner }; @@ -167,6 +172,17 @@ class FixSRD : public Fix { int maxstencil; // max # of bins stencil array can hold int **stencil; // list of 3d bin offsets a big particle can overlap + // persistent data for line/tri collision calculations + + double tfraction,theta0,theta1; + double xs0[3],xs1[3],xsc[3]; + double xb0[3],xb1[3],xbc[3]; + double nbc[3]; + + // shared data for triangle collision calculations + + // private functions + void reset_velocities(); void vbin_comm(int); void vbin_pack(BinAve *, int, int *, double *); @@ -177,6 +193,8 @@ class FixSRD : public Fix { int inside_sphere(double *, double *, Big *); int inside_ellipsoid(double *, double *, Big *); + int inside_line(double *, double *, double *, double *, Big *, double); + int inside_tri(double *, double *, double *, double *, Big *, double); int inside_wall(double *, int); double collision_sphere_exact(double *, double *, double *, double *, @@ -187,18 +205,19 @@ class FixSRD : public Fix { Big *, double *, double *, double *); void collision_ellipsoid_inexact(double *, double *, Big *, double *, double *, double *); + double collision_line_exact(double *, double *, double *, double *, + Big *, double, double *, double *, double *); + double collision_tri_exact(double *, double *, double *, double *, + Big *, double, double *, double *, double *); double collision_wall_exact(double *, int, double *, double *, double *, double *); void collision_wall_inexact(double *, int, double *, double *, double *); - void slip_sphere(double *, double *, double *, double *); - void slip_ellipsoid(double *, double *, double *, Big *, - double *, double *, double *); + void slip(double *, double *, double *, Big *, + double *, double *, double *); void slip_wall(double *, int, double *, double *); - - void noslip(double *, double *, double *, Big *, + void noslip(double *, double *, double *, Big *, int, double *, double *, double *); - void noslip_wall(double *, int, double *, double *, double *); void force_torque(double *, double *, double *, double *, double *, double *); @@ -217,11 +236,12 @@ class FixSRD : public Fix { double point_bin_distance(double *, int, int, int); double bin_bin_distance(int, int, int); - void exyz_from_q(double *, double *, double *, double *); - void omega_from_mq(double *, double *, double *, double *, - double, double *, double *); void velocity_stats(int); + double newton_raphson(double, double); + void lineside(double, double &, double &); + void triside(double, double &, double &); + double distance(int, int); void print_collision(int, int, int, double, double, double *, double *, double *, int); diff --git a/src/USER-CG-CMM/angle_cg_cmm.cpp b/src/USER-CG-CMM/angle_cg_cmm.cpp index 7d9800808a..070d65c5b8 100644 --- a/src/USER-CG-CMM/angle_cg_cmm.cpp +++ b/src/USER-CG-CMM/angle_cg_cmm.cpp @@ -24,10 +24,12 @@ #include "domain.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 0.001 @@ -323,7 +325,7 @@ void AngleCGCMM::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { k[i] = k_one; // convert theta0 from degrees to radians - theta0[i] = theta0_one/180.0 * PI; + theta0[i] = theta0_one/180.0 * MY_PI; epsilon[i] = epsilon_one; sigma[i] = sigma_one; rcut[i] = rcut_one; diff --git a/src/USER-CG-CMM/pair_cmm_common.cpp b/src/USER-CG-CMM/pair_cmm_common.cpp index 81d142f568..4e1606d587 100644 --- a/src/USER-CG-CMM/pair_cmm_common.cpp +++ b/src/USER-CG-CMM/pair_cmm_common.cpp @@ -23,8 +23,10 @@ #include "string.h" #include "ctype.h" #include "math.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; #define SMALL 1.0e-6 @@ -302,15 +304,14 @@ double PairCMMCommon::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); #endif } diff --git a/src/USER-CUDA/Install.sh b/src/USER-CUDA/Install.sh index 3dc143471f..56f0dc80b9 100755 --- a/src/USER-CUDA/Install.sh +++ b/src/USER-CUDA/Install.sh @@ -82,6 +82,12 @@ if (test $1 = 1) then cp pair_eam_alloy_cuda.h .. cp pair_eam_cuda.h .. cp pair_eam_fs_cuda.h .. + cp pair_sw_cuda.h .. + cp pair_sw_cuda.cpp .. + cp pair_tersoff_cuda.h .. + cp pair_tersoff_cuda.cpp .. + cp pair_tersoff_zbl_cuda.h .. + cp pair_tersoff_zbl_cuda.cpp .. fi if (test -e ../pair_gran_hooke.cpp) then @@ -193,12 +199,9 @@ if (test $1 = 1) then cp verlet_cuda.h .. cp cuda.h .. - cp cuda_common.h .. cp cuda_data.h .. cp cuda_modify_flags.h .. cp cuda_neigh_list.h .. - cp cuda_precision.h .. - cp cuda_shared.h .. elif (test $1 = 0) then @@ -341,12 +344,15 @@ elif (test $1 = 0) then rm -f ../pppm_cuda.h rm -f ../verlet_cuda.h + rm -f ../pair_sw_cuda.h + rm -f ../pair_sw_cuda.cpp + rm -f ../pair_tersoff_cuda.h + rm -f ../pair_tersoff_cuda.cpp + rm -f ../pair_tersoff_zbl_cuda.h + rm -f ../pair_tersoff_zbl_cuda.cpp + rm -f ../cuda.h - rm -f ../cuda_common.h rm -f ../cuda_data.h rm -f ../cuda_modify_flags.h rm -f ../cuda_neigh_list.h - rm -f ../cuda_precision.h - rm -f ../cuda_shared.h - fi diff --git a/src/USER-CUDA/comm_cuda.cpp b/src/USER-CUDA/comm_cuda.cpp index 8e75f93ba5..ea4a4ee6a6 100644 --- a/src/USER-CUDA/comm_cuda.cpp +++ b/src/USER-CUDA/comm_cuda.cpp @@ -41,6 +41,9 @@ using namespace LAMMPS_NS; #define BUFFACTOR 1.5 #define BUFMIN 1000 #define BUFEXTRA 1000 + + + #define BIG 1.0e20 enum{SINGLE,MULTI}; @@ -137,6 +140,7 @@ void CommCuda::init() void CommCuda::setup() { + if(cuda->shared_data.pair.neighall) cutghostuser = MAX(2.0*neighbor->cutneighmax,cutghostuser); Comm::setup(); //upload changed geometry to device diff --git a/src/USER-CUDA/cuda.cpp b/src/USER-CUDA/cuda.cpp index 39261bd7c0..819357bc16 100644 --- a/src/USER-CUDA/cuda.cpp +++ b/src/USER-CUDA/cuda.cpp @@ -46,6 +46,8 @@ using namespace LAMMPS_NS; + + Cuda::Cuda(LAMMPS *lmp) : Pointers(lmp) { cuda_exists=true; @@ -309,6 +311,7 @@ void Cuda::setSharedDataZero() shared_data.pair.special_lj = 0; shared_data.pair.special_coul = 0; + shared_data.pair.neighall = false; shared_data.pppm.cudable_force = 0; diff --git a/src/USER-CUDA/cuda_precision.h b/src/USER-CUDA/cuda_precision.h deleted file mode 100644 index 5b7d6a6843..0000000000 --- a/src/USER-CUDA/cuda_precision.h +++ /dev/null @@ -1,269 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - - Original Version: - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - See the README file in the top-level LAMMPS directory. - - ----------------------------------------------------------------------- - - USER-CUDA Package and associated modifications: - https://sourceforge.net/projects/lammpscuda/ - - Christian Trott, christian.trott@tu-ilmenau.de - Lars Winterfeld, lars.winterfeld@tu-ilmenau.de - Theoretical Physics II, University of Technology Ilmenau, Germany - - See the README file in the USER-CUDA directory. - - This software is distributed under the GNU General Public License. -------------------------------------------------------------------------- */ - -#ifndef CUDA_PRECISION_H_ -#define CUDA_PRECISION_H_ -/* This File gives Type definitions for mixed precision calculation in the cuda part of LAMMPS-CUDA. - * Predefined behaviour is given by global CUDA_PRECISION (can be overwritten during compilation). - * ***_FLOAT: type definition of given property - * ***_F: constant extension in code (1.0 is interpreted as double while 1.0f is interpreted as float, now use: 1.0CUDA_F) - */ - -#ifdef CUDA_USE_BINNING -#define CUDA_IF_BINNING(a) a -#else -#define CUDA_IF_BINNING(a) -#endif - -//GLOBAL - -#ifdef CUDA_PRECISION - #if CUDA_PRECISION == 1 - #define CUDA_FLOAT float - #define CUDA_F(x) x##f - #endif - #if CUDA_PRECISION == 2 - #define CUDA_FLOAT double - #define CUDA_F(x) x - #endif -#endif - -#ifndef CUDA_PRECISION - #define CUDA_FLOAT double - #define CUDA_F(x) x - #define CUDA_PRECISION 2 -#endif -//-------------------------------- -//-----------FFT----------------- -//-------------------------------- - -#ifdef FFT_PRECISION_CU - #if FFT_PRECISION_CU == 1 - #define FFT_FLOAT float - #define FFT_F(x) x##f - #endif - #if FFT_PRECISION_CU == 2 - #define FFT_FLOAT double - #define FFT_F(x) x - #endif -#endif - -#ifndef FFT_PRECISION_CU - #define FFT_FLOAT CUDA_FLOAT - #define FFT_F(x) CUDA_F(x) - #define FFT_PRECISION_CU CUDA_PRECISION -#endif - -//-------------------------------- -//-----------PPPM----------------- -//-------------------------------- - -#ifdef PPPM_PRECISION - #if PPPM_PRECISION == 1 - #define PPPM_FLOAT float - #define PPPM_F(x) x##f - #endif - #if PPPM_PRECISION == 2 - #define PPPM_FLOAT double - #define PPPM_F(x) x - #endif -#endif - -#ifndef PPPM_PRECISION - #define PPPM_FLOAT CUDA_FLOAT - #define PPPM_F(x) CUDA_F(x) - #define PPPM_PRECISION CUDA_PRECISION -#endif - -//-------------------------------- -//-----------FORCE----------------- -//-------------------------------- - - -#ifdef F_PRECISION - #if F_PRECISION == 1 - #define F_FLOAT float - #define F_F(x) x##f - #endif - #if F_PRECISION == 2 - #define F_FLOAT double - #define F_F(x) x - #endif -#endif - -#ifndef F_PRECISION - #define F_FLOAT CUDA_FLOAT - #define F_F(x) CUDA_F(x) - #define F_PRECISION CUDA_PRECISION -#endif - -#if F_PRECISION == 1 -#define _SQRT_ sqrtf -#define _RSQRT_ rsqrtf -#define _EXP_ expf -#else -#define _SQRT_ sqrt -#define _RSQRT_ rsqrt -#define _EXP_ exp -#endif - -#if F_PRECISION == 2 -struct F_FLOAT2 -{ - F_FLOAT x; - F_FLOAT y; -}; -struct F_FLOAT3 -{ - F_FLOAT x; - F_FLOAT y; - F_FLOAT z; -}; -struct F_FLOAT4 -{ - F_FLOAT x; - F_FLOAT y; - F_FLOAT z; - F_FLOAT w; -}; -#else -#define F_FLOAT2 float2 -#define F_FLOAT3 float3 -#define F_FLOAT4 float4 -#endif -//-------------------------------- -//-----------ENERGY----------------- -//-------------------------------- - -#ifndef ENERGY_PRECISION - #define ENERGY_FLOAT CUDA_FLOAT - #define ENERGY_F(x) CUDA_F(x) -#endif - -#ifdef ENERGY_PRECISION - #if ENERGY_PRECISION == 1 - #define ENERGY_FLOAT float - #define ENERGY_F(x) x##f - #endif - #if ENERGY_PRECISION == 2 - #define ENERGY_FLOAT double - #define ENERGY_F(x) x - #endif -#endif - -#ifndef ENERGY_PRECISION - #define ENERGY_FLOAT CUDA_FLOAT - #define ENERGY_F(x) CUDA_F(x) - #define ENERGY_PRECISION CUDA_PRECISION -#endif - -//-------------------------------- -//-----------POSITIONS------------ -//-------------------------------- - -#ifdef X_PRECISION - #if X_PRECISION == 1 - #define X_FLOAT float - #define X_F(x) x##f - #endif - #if X_PRECISION == 2 - #define X_FLOAT double - #define X_F(x) x - #endif -#endif - -#ifndef X_PRECISION - #define X_FLOAT CUDA_FLOAT - #define X_F(x) CUDA_F(x) - #define X_PRECISION CUDA_PRECISION -#endif - -#if X_PRECISION == 2 -struct X_FLOAT2 -{ - X_FLOAT x; - X_FLOAT y; -}; -struct X_FLOAT3 -{ - X_FLOAT x; - X_FLOAT y; - X_FLOAT z; -}; -struct X_FLOAT4 -{ - X_FLOAT x; - X_FLOAT y; - X_FLOAT z; - X_FLOAT w; -}; -#else -#define X_FLOAT2 float2 -#define X_FLOAT3 float3 -#define X_FLOAT4 float4 -#endif - -//-------------------------------- -//-----------velocities----------- -//-------------------------------- - -#ifdef V_PRECISION - #if V_PRECISION == 1 - #define V_FLOAT float - #define V_F(x) x##f - #endif - #if V_PRECISION == 2 - #define V_FLOAT double - #define V_F(x) x - #endif -#endif - -#ifndef V_PRECISION - #define V_FLOAT CUDA_FLOAT - #define V_F(x) CUDA_F(x) - #define V_PRECISION CUDA_PRECISION -#endif - -#if V_PRECISION == 2 -struct V_FLOAT4 -{ - V_FLOAT x; - V_FLOAT y; - V_FLOAT z; - V_FLOAT w; -}; -#else -#define V_FLOAT4 float4 -#endif - -#ifdef NO_PREC_TIMING -struct timespec_2 -{ - unsigned int tv_sec; - unsigned int tv_nsec; -}; - -#define timespec timespec_2 -#define clock_gettime(a,b) -#endif -#endif /*CUDA_PRECISION_H_*/ diff --git a/src/USER-CUDA/cuda_shared.h b/src/USER-CUDA/cuda_shared.h deleted file mode 100644 index f7983fff05..0000000000 --- a/src/USER-CUDA/cuda_shared.h +++ /dev/null @@ -1,378 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - - Original Version: - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - See the README file in the top-level LAMMPS directory. - - ----------------------------------------------------------------------- - - USER-CUDA Package and associated modifications: - https://sourceforge.net/projects/lammpscuda/ - - Christian Trott, christian.trott@tu-ilmenau.de - Lars Winterfeld, lars.winterfeld@tu-ilmenau.de - Theoretical Physics II, University of Technology Ilmenau, Germany - - See the README file in the USER-CUDA directory. - - This software is distributed under the GNU General Public License. -------------------------------------------------------------------------- */ - -#ifndef _CUDA_SHARED_H_ -#define _CUDA_SHARED_H_ -#include "cuda_precision.h" - -#define CUDA_MAX_DEBUG_SIZE 1000 //size of debugdata array (allows for so many doubles or twice as many int) - -struct dev_array -{ - void* dev_data; // pointer to memory address on cuda device - unsigned dim[3]; // array dimensions -}; - -struct cuda_shared_atom // relevent data from atom class -{ - dev_array dx; // cumulated distance for binning settings - dev_array x; // position - dev_array v; // velocity - dev_array f; // force - dev_array tag; - dev_array type; // global ID number, there are ghosttype = ntypes (ntypescuda=ntypes+1) - dev_array mask; - dev_array image; - dev_array q; // charges - dev_array mass; // per-type masses - dev_array rmass; // per-atom masses - dev_array radius; // per-atom radius - dev_array density; - dev_array omega; - dev_array torque; - dev_array molecule; - - dev_array special; - int maxspecial; - dev_array nspecial; - int* special_flag; - int molecular; - - dev_array eatom; // per-atom energy - dev_array vatom; // per-atom virial - int need_eatom; - int need_vatom; - - dev_array x_type; // position + type in X_FLOAT4 struct - dev_array v_radius; // velociyt + radius in V_FLOAT4 struct currently only used for granular atom_style - dev_array omega_rmass; // velociyt + radius in V_FLOAT4 struct currently only used for granular atom_style - - double* mass_host; // remember per-type host pointer to masses - //int natoms; // total # of atoms in system, could be 0 - int nghost; // and ghost atoms on this proc - int nlocal; // # of owned - int nall; // total # of atoms in this proc - int nmax; // max # of owned+ghost in arrays on this proc - int ntypes; - int q_flag; // do we have charges? - int rmass_flag; // do we have per-atom masses? - int firstgroup; - int nfirst; - - int update_nlocal; - int update_nmax; - - dev_array xhold; // position at last neighboring - X_FLOAT triggerneighsq; // maximum square movement before reneighboring - int reneigh_flag; // is reneighboring necessary - int maxhold; // size of xhold - int dist_check; //perform distance check for reneighboring - dev_array binned_id; //id of each binned atom (not tag!!) - dev_array binned_idnew; //new id of each binned atom for sorting basically setting atom[binned_id[k]] at atom[binned_newid[k]] - float bin_extraspace; - int bin_dim[3]; - int bin_nmax; - dev_array map_array; -}; - -struct cuda_shared_pair // relevent data from pair class -{ - char cudable_force; // check for (cudable_force!=0) - X_FLOAT cut_global; - X_FLOAT cut_inner_global; - X_FLOAT cut_coul_global; - double** cut; // type-type cutoff - double** cutsq; // type-type cutoff - double** cut_inner; // type-type cutoff for coul - double** cut_coul; // type-type cutoff for coul - double** coeff1; // tpye-type pair parameters - double** coeff2; - double** coeff3; - double** coeff4; - double** coeff5; - double** coeff6; - double** coeff7; - double** coeff8; - double** coeff9; - double** coeff10; - double** offset; - double* special_lj; - double* special_coul; - dev_array virial; // ENERGY_FLOAT - dev_array eng_vdwl; // ENERGY_FLOAT - dev_array eng_coul; // ENERGY_FLOAT - X_FLOAT cut_coulsq_global; - F_FLOAT g_ewald,kappa; - int freeze_group_bit; - - dev_array coeff1_gm; - dev_array coeff2_gm; - dev_array coeff3_gm; - dev_array coeff4_gm; - dev_array coeff5_gm; - dev_array coeff6_gm; - dev_array coeff7_gm; - dev_array coeff8_gm; - dev_array coeff9_gm; - dev_array coeff10_gm; - - int lastgridsize; - int n_energy_virial; - int collect_forces_later; - int use_block_per_atom; - int override_block_per_atom; - -}; - -struct cuda_shared_domain // relevent data from domain class -{ - X_FLOAT sublo[3]; // orthogonal box -> sub-box bounds on this proc - X_FLOAT subhi[3]; - X_FLOAT boxlo[3]; - X_FLOAT boxhi[3]; - X_FLOAT prd[3]; - int periodicity[3]; // xyz periodicity as array - - int triclinic; - X_FLOAT xy; - X_FLOAT xz; - X_FLOAT yz; - X_FLOAT boxlo_lamda[3]; - X_FLOAT boxhi_lamda[3]; - X_FLOAT prd_lamda[3]; - X_FLOAT h[6]; - X_FLOAT h_inv[6]; - V_FLOAT h_rate[6]; - int update; -}; - -struct cuda_shared_pppm -{ - char cudable_force; -#ifdef FFT_CUFFT - FFT_FLOAT* work1; - FFT_FLOAT* work2; - FFT_FLOAT* work3; - PPPM_FLOAT* greensfn; - PPPM_FLOAT* fkx; - PPPM_FLOAT* fky; - PPPM_FLOAT* fkz; - PPPM_FLOAT* vg; -#endif - int* part2grid; - PPPM_FLOAT* density_brick; - int* density_brick_int; - PPPM_FLOAT density_intScale; - PPPM_FLOAT* vdx_brick; - PPPM_FLOAT* vdy_brick; - PPPM_FLOAT* vdz_brick; - PPPM_FLOAT* density_fft; - ENERGY_FLOAT* energy; - ENERGY_FLOAT* virial; - int nxlo_in; - int nxhi_in; - int nxlo_out; - int nxhi_out; - int nylo_in; - int nyhi_in; - int nylo_out; - int nyhi_out; - int nzlo_in; - int nzhi_in; - int nzlo_out; - int nzhi_out; - int nx_pppm; - int ny_pppm; - int nz_pppm; - PPPM_FLOAT qqrd2e; - int order; - // float3 sublo; - PPPM_FLOAT* rho_coeff; - int nmax; - int nlocal; - PPPM_FLOAT* debugdata; - PPPM_FLOAT delxinv; - PPPM_FLOAT delyinv; - PPPM_FLOAT delzinv; - int nlower; - int nupper; - PPPM_FLOAT shiftone; - -}; - -struct cuda_shared_comm -{ - int maxswap; - int maxlistlength; - dev_array pbc; - dev_array slablo; - dev_array slabhi; - dev_array multilo; - dev_array multihi; - dev_array sendlist; - int grow_flag; - int comm_phase; - - int nsend; - int* nsend_swap; - int* send_size; - int* recv_size; - double** buf_send; - void** buf_send_dev; - double** buf_recv; - void** buf_recv_dev; - void* buffer; - int buffer_size; - double overlap_split_ratio; -}; - -struct cuda_shared_neighlist // member of CudaNeighList, has no instance in cuda_shared_data -{ - int maxlocal; - int inum; // # of I atoms neighbors are stored for local indices of I atoms - int inum_border2; - dev_array inum_border; // # of atoms which interact with border atoms - dev_array ilist; - dev_array ilist_border; - dev_array numneigh; - dev_array numneigh_inner; - dev_array numneigh_border; - dev_array firstneigh; - dev_array neighbors; - dev_array neighbors_border; - dev_array neighbors_inner; - int maxpage; - dev_array page_pointers; - dev_array* pages; - int maxneighbors; - int neigh_lists_per_page; - double** cutneighsq; - CUDA_FLOAT* cu_cutneighsq; - int* binned_id; - int* bin_dim; - int bin_nmax; - float bin_extraspace; - double maxcut; - dev_array ex_type; - int nex_type; - dev_array ex1_bit; - dev_array ex2_bit; - int nex_group; - dev_array ex_mol_bit; - int nex_mol; - -}; - -struct cuda_compile_settings // this is used to compare compile settings (i.e. precision) of the cu files, and the cpp files -{ - int prec_glob; - int prec_x; - int prec_v; - int prec_f; - int prec_pppm; - int prec_fft; - int cufft; - int arch; -}; - -struct cuda_timings_struct -{ - //Debug: - double test1; - double test2; - //transfers - double transfer_upload_tmp_constr; - double transfer_download_tmp_deconstr; - - //communication - double comm_forward_total; - double comm_forward_mpi_upper; - double comm_forward_mpi_lower; - double comm_forward_kernel_pack; - double comm_forward_kernel_unpack; - double comm_forward_kernel_self; - double comm_forward_upload; - double comm_forward_download; - - double comm_exchange_total; - double comm_exchange_mpi; - double comm_exchange_kernel_pack; - double comm_exchange_kernel_unpack; - double comm_exchange_kernel_fill; - double comm_exchange_cpu_pack; - double comm_exchange_upload; - double comm_exchange_download; - - double comm_border_total; - double comm_border_mpi; - double comm_border_kernel_pack; - double comm_border_kernel_unpack; - double comm_border_kernel_self; - double comm_border_kernel_buildlist; - double comm_border_upload; - double comm_border_download; - - //pair forces - double pair_xtype_conversion; - double pair_kernel; - double pair_virial; - double pair_force_collection; - - //neighbor - double neigh_bin; - double neigh_build; - double neigh_special; - - //PPPM - double pppm_particle_map; - double pppm_make_rho; - double pppm_brick2fft; - double pppm_poisson; - double pppm_fillbrick; - double pppm_fieldforce; - double pppm_compute; - -}; - -struct cuda_shared_data // holds space for all relevent data from the different classes -{ - void* buffer; //holds temporary GPU data [data used in subroutines, which has not to be consistend outside of that routine] - int buffersize; //maxsize of buffer - int buffer_new; //should be 1 if the pointer to buffer has changed - void* flag; - void* debugdata; //array for easily collecting debugdata from device class cuda contains the corresponding cu_debugdata and host array - cuda_shared_atom atom; - cuda_shared_pair pair; - cuda_shared_domain domain; - cuda_shared_pppm pppm; - cuda_shared_comm comm; - cuda_compile_settings compile_settings; - cuda_timings_struct cuda_timings; - int exchange_dim; - int me; //mpi rank - unsigned int datamask; - int overlap_comm; -}; - - -#endif // #ifndef _CUDA_SHARED_H_ diff --git a/src/USER-CUDA/fix_gravity_cuda.cpp b/src/USER-CUDA/fix_gravity_cuda.cpp index 8c6d8488c8..36d7022fa3 100644 --- a/src/USER-CUDA/fix_gravity_cuda.cpp +++ b/src/USER-CUDA/fix_gravity_cuda.cpp @@ -30,12 +30,13 @@ #include "update.h" #include "domain.h" #include "respa.h" -#include "error.h" #include "cuda.h" #include "cuda_modify_flags.h" - +#include "math_const.h" +#include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{CHUTE,SPHERICAL,GRADIENT,VECTOR}; @@ -79,8 +80,7 @@ FixGravityCuda::FixGravityCuda(LAMMPS *lmp, int narg, char **arg) : zdir = atof(arg[7]); } else error->all(FLERR,"Illegal fix gravity command"); - double PI = 4.0*atan(1.0); - degree2rad = PI/180.0; + degree2rad = MY_PI/180.0; if (style == CHUTE || style == SPHERICAL || style == GRADIENT) { if (domain->dimension == 3) { diff --git a/src/USER-CUDA/fix_shake_cuda.cpp b/src/USER-CUDA/fix_shake_cuda.cpp index 219ac679bd..cbcb9acaef 100644 --- a/src/USER-CUDA/fix_shake_cuda.cpp +++ b/src/USER-CUDA/fix_shake_cuda.cpp @@ -34,8 +34,10 @@ #include "error.h" #include "cuda.h" #include "cuda_modify_flags.h" +#include "math_const.h" using namespace LAMMPS_NS; +using namespace MathConst; #define BIG 1.0e20 #define MASSDELTA 0.1 @@ -53,7 +55,6 @@ FixShakeCuda::FixShakeCuda(LAMMPS *lmp, int narg, char **arg) : MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); neighbor_step=true; - PI = 4.0*atan(1.0); virial_flag = 1; create_attribute = 1; @@ -2183,7 +2184,7 @@ void FixShakeCuda::stats() r3 = sqrt(delx*delx + dely*dely + delz*delz); angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2)); - angle *= 180.0/PI; + angle *= 180.0/MY_PI; m = shake_type[i][2]; a_count[m]++; a_ave[m] += angle; diff --git a/src/USER-CUDA/fix_shake_cuda.h b/src/USER-CUDA/fix_shake_cuda.h index 18ea64f983..b0ebe584d7 100644 --- a/src/USER-CUDA/fix_shake_cuda.h +++ b/src/USER-CUDA/fix_shake_cuda.h @@ -53,7 +53,6 @@ class FixShakeCuda : public Fix { private: class Cuda *cuda; int me,nprocs; - double PI; double tolerance; // SHAKE tolerance int max_iter; // max # of SHAKE iterations int output_every; // SHAKE stat output every so often diff --git a/src/USER-CUDA/neighbor_cuda.cpp b/src/USER-CUDA/neighbor_cuda.cpp index 99bf2dce3c..dc5af9f2f8 100644 --- a/src/USER-CUDA/neighbor_cuda.cpp +++ b/src/USER-CUDA/neighbor_cuda.cpp @@ -26,6 +26,9 @@ using namespace LAMMPS_NS; + + + enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp /* ---------------------------------------------------------------------- */ @@ -56,9 +59,9 @@ void NeighborCuda::choose_build(int index, NeighRequest *rq) { Neighbor::choose_build(index,rq); - if (rq->full && style == NSQ && rq->ghost == 0 && rq->cudable) + if (rq->full && style == NSQ && rq->cudable) pair_build[index] = (Neighbor::PairPtr) &NeighborCuda::full_nsq_cuda; - else if (rq->full && style == BIN && rq->ghost == 0 && rq->cudable) + else if (rq->full && style == BIN && rq->cudable) pair_build[index] = (Neighbor::PairPtr) &NeighborCuda::full_bin_cuda; } diff --git a/src/USER-CUDA/pair_sw_cuda.cpp b/src/USER-CUDA/pair_sw_cuda.cpp new file mode 100644 index 0000000000..601ad7f2cf --- /dev/null +++ b/src/USER-CUDA/pair_sw_cuda.cpp @@ -0,0 +1,209 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + 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: Paul Crozier (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_sw_cuda.h" +#include "cuda_data.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "cuda_neigh_list.h" +#include "update.h" +#include "integrate.h" +#include "respa.h" +#include "memory.h" +#include "error.h" +#include "cuda.h" + +using namespace LAMMPS_NS; + + + + +/* ---------------------------------------------------------------------- */ + +PairSWCuda::PairSWCuda(LAMMPS *lmp) : PairSW(lmp) +{ + cuda = lmp->cuda; + if(cuda == NULL) + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + + allocated2 = false; + params_f = NULL; + cuda->setSystemParams(); + cuda->shared_data.pair.cudable_force = 1; + cuda->shared_data.pair.override_block_per_atom = 0; + cuda->shared_data.pair.neighall = true; + init = false; +} + +/* ---------------------------------------------------------------------- + remember pointer to arrays in cuda shared data +------------------------------------------------------------------------- */ + +void PairSWCuda::allocate() +{ + if(! allocated) PairSW::allocate(); + if(! allocated2) + { + allocated2 = true; + cuda->shared_data.pair.cutsq = cutsq; + cuda->shared_data.pair.special_lj = force->special_lj; + cuda->shared_data.pair.special_coul = force->special_coul; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairSWCuda::compute(int eflag, int vflag) +{ + if(!init) {Cuda_PairSWCuda_Init(&cuda->shared_data,params_f,map, &elem2param[0][0][0],nelements); init=true;} + if (eflag || vflag) ev_setup(eflag,vflag); + if(eflag) cuda->cu_eng_vdwl->upload(); + if(vflag) cuda->cu_virial->upload(); + + Cuda_PairSWCuda(& cuda->shared_data, & cuda_neigh_list->sneighlist, eflag, vflag, eflag_atom, vflag_atom);//,&elem2param[0][0][0],map + if(not cuda->shared_data.pair.collect_forces_later) + { + if(eflag) cuda->cu_eng_vdwl->download(); + if(vflag) cuda->cu_virial->download(); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairSWCuda::settings(int narg, char **arg) +{ + PairSW::settings(narg, arg); +} + +/* ---------------------------------------------------------------------- */ + +void PairSWCuda::coeff(int narg, char **arg) +{ + PairSW::coeff(narg, arg); + allocate(); + params_f = (ParamSW_Float *) memory->srealloc(params_f,maxparam*sizeof(ParamSW_Float), + "pair:params_f"); + for(int i=0;ishared_data.pair.cut_global = cutmax; +} + +void PairSWCuda::init_style() +{ + MYDBG(printf("# CUDA PairSWCuda::init_style start\n"); ) + + int irequest; + + irequest = neighbor->request(this); + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->cudable = 1; + neighbor->requests[irequest]->ghost = 1; + + + MYDBG(printf("# CUDA PairSWCuda::init_style end\n"); ) +} + +void PairSWCuda::init_list(int id, NeighList *ptr) +{ + MYDBG(printf("# CUDA PairSWCuda::init_list\n");) + PairSW::init_list(id, ptr); + // right now we can only handle verlet (id 0), not respa + if(id == 0) cuda_neigh_list = cuda->registerNeighborList(ptr); + // see Neighbor::init() for details on lammps lists' logic + MYDBG(printf("# CUDA PairSWCuda::init_list end\n");) + cu_params_f = (ParamSW_Float*) CudaWrapper_AllocCudaData(sizeof(ParamSW_Float)*maxparam); + CudaWrapper_UploadCudaData((void*) params_f,(void*) cu_params_f,sizeof(ParamSW_Float)*maxparam); + cu_elem2param = new cCudaData ((int*) elem2param, nelements,nelements,nelements); + cu_elem2param->upload(); + cu_map = new cCudaData ( map,atom->ntypes+1 ); + cu_map->upload(); +} + +void PairSWCuda::ev_setup(int eflag, int vflag) +{ + int maxeatomold=maxeatom; + PairSW::ev_setup(eflag,vflag); + + if (eflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_eatom; cuda->cu_eatom = new cCudaData ((double*)eatom, & cuda->shared_data.atom.eatom , atom->nmax );} + + if (vflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_vatom; cuda->cu_vatom = new cCudaData ((double*)vatom, & cuda->shared_data.atom.vatom , atom->nmax, 6 );} +} + + diff --git a/src/USER-CUDA/pair_sw_cuda.h b/src/USER-CUDA/pair_sw_cuda.h new file mode 100644 index 0000000000..be9ba9bb3d --- /dev/null +++ b/src/USER-CUDA/pair_sw_cuda.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(sw/cuda,PairSWCuda) + +#else + +#ifndef PAIR_SW_CUDA_H +#define PAIR_SW_CUDA_H + +#include "pair_sw_cuda_cu.h" +#include "pair_sw.h" +#include "cuda_data.h" + +namespace LAMMPS_NS { + +class PairSWCuda : public PairSW +{ + public: + PairSWCuda(class LAMMPS *); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + void init_list(int, class NeighList *); + void init_style(); + void ev_setup(int eflag, int vflag); + protected: + + class Cuda *cuda; + void allocate(); + bool allocated2; + class CudaNeighList* cuda_neigh_list; + ParamSW_Float* params_f; + ParamSW_Float* cu_params_f; + cCudaData* cu_elem2param; + cCudaData* cu_map; + bool init; + bool iszbl; +}; + +} + +#endif +#endif diff --git a/src/USER-CUDA/pair_tersoff_cuda.cpp b/src/USER-CUDA/pair_tersoff_cuda.cpp new file mode 100644 index 0000000000..4f1dba4e31 --- /dev/null +++ b/src/USER-CUDA/pair_tersoff_cuda.cpp @@ -0,0 +1,206 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + 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: Paul Crozier (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_tersoff_cuda.h" +#include "cuda_data.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "cuda_neigh_list.h" +#include "update.h" +#include "integrate.h" +#include "respa.h" +#include "memory.h" +#include "error.h" +#include "cuda.h" + +using namespace LAMMPS_NS; + + + + +/* ---------------------------------------------------------------------- */ + +PairTersoffCuda::PairTersoffCuda(LAMMPS *lmp) : PairTersoff(lmp) +{ + cuda = lmp->cuda; + if(cuda == NULL) + error->all(FLERR,"You cannot use a /cuda class, without activating 'cuda' acceleration. Provide '-c on' as command-line argument to LAMMPS.."); + + allocated2 = false; + params_f = NULL; + cuda->setSystemParams(); + cuda->shared_data.pair.cudable_force = 1; + cuda->shared_data.pair.override_block_per_atom = 0; + cuda->shared_data.pair.neighall = true; + init = false; + iszbl = false; +} + +/* ---------------------------------------------------------------------- + remember pointer to arrays in cuda shared data +------------------------------------------------------------------------- */ + +void PairTersoffCuda::allocate() +{ + if(! allocated) PairTersoff::allocate(); + if(! allocated2) + { + allocated2 = true; + cuda->shared_data.pair.cutsq = cutsq; + cuda->shared_data.pair.special_lj = force->special_lj; + cuda->shared_data.pair.special_coul = force->special_coul; + } +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffCuda::compute(int eflag, int vflag) +{ + if(!init) {Cuda_PairTersoffCuda_Init(&cuda->shared_data,params_f,map, &elem2param[0][0][0],nelements,iszbl); init=true;} + if (eflag || vflag) ev_setup(eflag,vflag); + if(eflag) cuda->cu_eng_vdwl->upload(); + if(vflag) cuda->cu_virial->upload(); + + Cuda_PairTersoffCuda(& cuda->shared_data, & cuda_neigh_list->sneighlist, eflag, vflag, eflag_atom, vflag_atom);//,&elem2param[0][0][0],map + if(not cuda->shared_data.pair.collect_forces_later) + { + if(eflag) cuda->cu_eng_vdwl->download(); + if(vflag) cuda->cu_virial->download(); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffCuda::settings(int narg, char **arg) +{ + PairTersoff::settings(narg, arg); +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffCuda::coeff(int narg, char **arg) +{ + PairTersoff::coeff(narg, arg); + allocate(); + params_f = (Param_Float *) memory->srealloc(params_f,maxparam*sizeof(Param_Float), + "pair:params_f"); + for(int i=0;ishared_data.pair.cut_global = cutmax; +} + +void PairTersoffCuda::init_style() +{ + MYDBG(printf("# CUDA PairTersoffCuda::init_style start\n"); ) + + int irequest; + + irequest = neighbor->request(this); + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->cudable = 1; + neighbor->requests[irequest]->ghost = 1; + + + MYDBG(printf("# CUDA PairTersoffCuda::init_style end\n"); ) +} + +void PairTersoffCuda::init_list(int id, NeighList *ptr) +{ + MYDBG(printf("# CUDA PairTersoffCuda::init_list\n");) + PairTersoff::init_list(id, ptr); + // right now we can only handle verlet (id 0), not respa + if(id == 0) cuda_neigh_list = cuda->registerNeighborList(ptr); + // see Neighbor::init() for details on lammps lists' logic + MYDBG(printf("# CUDA PairTersoffCuda::init_list end\n");) + cu_params_f = (Param_Float*) CudaWrapper_AllocCudaData(sizeof(Param_Float)*maxparam); + CudaWrapper_UploadCudaData((void*) params_f,(void*) cu_params_f,sizeof(Param_Float)*maxparam); + cu_elem2param = new cCudaData ((int*) elem2param, nelements,nelements,nelements); + cu_elem2param->upload(); + cu_map = new cCudaData ( map,atom->ntypes+1 ); + cu_map->upload(); +} + +void PairTersoffCuda::ev_setup(int eflag, int vflag) +{ + int maxeatomold=maxeatom; + PairTersoff::ev_setup(eflag,vflag); + + if (eflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_eatom; cuda->cu_eatom = new cCudaData ((double*)eatom, & cuda->shared_data.atom.eatom , atom->nmax );} + + if (vflag_atom && atom->nmax > maxeatomold) + {delete cuda->cu_vatom; cuda->cu_vatom = new cCudaData ((double*)vatom, & cuda->shared_data.atom.vatom , atom->nmax, 6 );} +} + + diff --git a/src/USER-CUDA/pair_tersoff_cuda.h b/src/USER-CUDA/pair_tersoff_cuda.h new file mode 100644 index 0000000000..34a06f91a9 --- /dev/null +++ b/src/USER-CUDA/pair_tersoff_cuda.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + + Original Version: + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + See the README file in the top-level LAMMPS directory. + + ----------------------------------------------------------------------- + + USER-CUDA Package and associated modifications: + https://sourceforge.net/projects/lammpscuda/ + + Christian Trott, christian.trott@tu-ilmenau.de + Lars Winterfeld, lars.winterfeld@tu-ilmenau.de + Theoretical Physics II, University of Technology Ilmenau, Germany + + See the README file in the USER-CUDA directory. + + This software is distributed under the GNU General Public License. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(tersoff/cuda,PairTersoffCuda) + +#else + +#ifndef PAIR_TERSOFF_CUDA_H +#define PAIR_TERSOFF_CUDA_H + +#include "pair_tersoff_cuda_cu.h" +#include "pair_tersoff.h" +#include "cuda_data.h" + +namespace LAMMPS_NS { + +class PairTersoffCuda : public PairTersoff +{ + public: + PairTersoffCuda(class LAMMPS *); + void compute(int, int); + void settings(int, char **); + void coeff(int, char **); + void init_list(int, class NeighList *); + void init_style(); + void ev_setup(int eflag, int vflag); + protected: + + class Cuda *cuda; + void allocate(); + bool allocated2; + class CudaNeighList* cuda_neigh_list; + Param_Float* params_f; + Param_Float* cu_params_f; + cCudaData* cu_elem2param; + cCudaData* cu_map; + bool init; + bool iszbl; +}; + +} + +#endif +#endif diff --git a/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp b/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp new file mode 100644 index 0000000000..45236da515 --- /dev/null +++ b/src/USER-CUDA/pair_tersoff_zbl_cuda.cpp @@ -0,0 +1,220 @@ +/* ---------------------------------------------------------------------- + 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: Aidan Thompson (SNL) - original Tersoff implementation + David Farrell (NWU) - ZBL addition +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "pair_tersoff_zbl_cuda.h" +#include "atom.h" +#include "update.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 "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define MAXLINE 1024 +#define DELTA 4 + +/* ---------------------------------------------------------------------- */ + +PairTersoffZBLCuda::PairTersoffZBLCuda(LAMMPS *lmp) : PairTersoffCuda(lmp) +{ + // hard-wired constants in metal or real units + // a0 = Bohr radius + // epsilon0 = permittivity of vacuum = q / energy-distance units + // e = unit charge + // 1 Kcal/mole = 0.043365121 eV + + if (strcmp(update->unit_style,"metal") == 0) { + global_a_0 = 0.529; + global_epsilon_0 = 0.00552635; + global_e = 1.0; + } else if (strcmp(update->unit_style,"real") == 0) { + global_a_0 = 0.529; + global_epsilon_0 = 0.00552635 * 0.043365121; + global_e = 1.0; + } else error->all(FLERR,"Pair tersoff/zbl requires metal or real units"); + iszbl = true; +} + +/* ---------------------------------------------------------------------- */ + +void PairTersoffZBLCuda::read_file(char *file) +{ + int params_per_line = 21; + char **words = new char*[params_per_line+1]; + + delete [] params; + params = NULL; + nparams = 0; + + // open file on proc 0 + + FILE *fp; + if (comm->me == 0) { + fp = fopen(file,"r"); + if (fp == NULL) { + char str[128]; + sprintf(str,"Cannot open Tersoff potential file %s",file); + error->one(FLERR,str); + } + } + + // 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,jelement,kelement; + 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 Tersoff 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; + + // ielement,jelement,kelement = 1st args + // if all 3 args are in element list, then parse this line + // else skip to next line + + for (ielement = 0; ielement < nelements; ielement++) + if (strcmp(words[0],elements[ielement]) == 0) break; + if (ielement == nelements) continue; + for (jelement = 0; jelement < nelements; jelement++) + if (strcmp(words[1],elements[jelement]) == 0) break; + if (jelement == nelements) continue; + for (kelement = 0; kelement < nelements; kelement++) + if (strcmp(words[2],elements[kelement]) == 0) break; + if (kelement == nelements) continue; + + // load up parameter settings and error check their values + + if (nparams == maxparam) { + maxparam += DELTA; + params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), + "pair:params"); + } + + params[nparams].ielement = ielement; + params[nparams].jelement = jelement; + params[nparams].kelement = kelement; + params[nparams].powerm = atof(words[3]); + params[nparams].gamma = atof(words[4]); + params[nparams].lam3 = atof(words[5]); + params[nparams].c = atof(words[6]); + params[nparams].d = atof(words[7]); + params[nparams].h = atof(words[8]); + params[nparams].powern = atof(words[9]); + params[nparams].beta = atof(words[10]); + params[nparams].lam2 = atof(words[11]); + params[nparams].bigb = atof(words[12]); + params[nparams].bigr = atof(words[13]); + params[nparams].bigd = atof(words[14]); + params[nparams].lam1 = atof(words[15]); + params[nparams].biga = atof(words[16]); + params[nparams].Z_i = atof(words[17]); + params[nparams].Z_j = atof(words[18]); + params[nparams].ZBLcut = atof(words[19]); + params[nparams].ZBLexpscale = atof(words[20]); + + // currently only allow m exponent of 1 or 3 + + params[nparams].powermint = int(params[nparams].powerm); + + if ( + params[nparams].lam3 < 0.0 || params[nparams].c < 0.0 || + params[nparams].d < 0.0 || params[nparams].powern < 0.0 || + params[nparams].beta < 0.0 || params[nparams].lam2 < 0.0 || + params[nparams].bigb < 0.0 || params[nparams].bigr < 0.0 || + params[nparams].bigd < 0.0 || + params[nparams].bigd > params[nparams].bigr || + params[nparams].lam3 < 0.0 || params[nparams].biga < 0.0 || + params[nparams].powerm - params[nparams].powermint != 0.0 || + (params[nparams].powermint != 3 && params[nparams].powermint != 1) || + params[nparams].gamma < 0.0 || + params[nparams].Z_i < 1.0 || params[nparams].Z_j < 1.0 || + params[nparams].ZBLcut < 0.0 || params[nparams].ZBLexpscale < 0.0) + error->all(FLERR,"Illegal Tersoff parameter"); + + nparams++; + } + + delete [] words; +} + +void PairTersoffZBLCuda::coeff(int narg, char **arg) +{ + PairTersoffCuda::coeff(narg, arg); + for(int i=0;i1) precisionmodify=arg[1][0]; else precisionmodify='='; - + nfactors = 3; factors = new int[nfactors]; factors[0] = 2; @@ -966,7 +968,7 @@ else energy *= 0.5*volume; energy -= g_ewald*qsqsum/1.772453851 + - 0.5*MY_PI*qsum*qsum / (g_ewald*g_ewald*volume); + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); energy *= qqrd2e; } diff --git a/src/USER-CUDA/verlet_cuda.cpp b/src/USER-CUDA/verlet_cuda.cpp index 599c9e8b97..f03ca0a07f 100644 --- a/src/USER-CUDA/verlet_cuda.cpp +++ b/src/USER-CUDA/verlet_cuda.cpp @@ -21,6 +21,7 @@ This software is distributed under the GNU General Public License. ------------------------------------------------------------------------- */ + #include #include #include @@ -56,6 +57,7 @@ using namespace LAMMPS_NS; #define MAKETIMEING + VerletCuda::VerletCuda(LAMMPS *lmp, int narg, char **arg) : Verlet(lmp, narg, arg) { cuda = lmp->cuda; if(cuda == NULL) @@ -132,20 +134,19 @@ void VerletCuda::setup() cuda->uploadAll(); neighbor->build(); neighbor->ncalls = 0; - cuda->uploadAllNeighborLists(); + if(atom->mass) cuda->cu_mass->upload(); if(cuda->cu_map_array) cuda->cu_map_array->upload(); - + // compute all forces ev_set(update->ntimestep); if(elist_atom) cuda->shared_data.atom.need_eatom = 1; if(vlist_atom) cuda->shared_data.atom.need_vatom = 1; if(elist_atom||vlist_atom) cuda->checkResize(); - int test_BpA_vs_TpA = true; timespec starttime; diff --git a/src/USER-EFF/atom_vec_electron.h b/src/USER-EFF/atom_vec_electron.h index b9372f62a6..6c527cacdd 100644 --- a/src/USER-EFF/atom_vec_electron.h +++ b/src/USER-EFF/atom_vec_electron.h @@ -60,7 +60,6 @@ class AtomVecElectron : public AtomVec { bigint memory_usage(); private: - double PI; int *tag,*type,*mask,*image; double **x,**v,**f; int *spin; diff --git a/src/USER-OMP/Install.sh b/src/USER-OMP/Install.sh index 40379fcc8f..c010cefdf8 100644 --- a/src/USER-OMP/Install.sh +++ b/src/USER-OMP/Install.sh @@ -6,7 +6,6 @@ for file in *_omp.cpp *_omp.h; do ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,` if (test $1 = 1) then - if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") then : # always install those files. elif (test ! -e ../$ofile) then @@ -16,12 +15,10 @@ for file in *_omp.cpp *_omp.h; do cp $file .. elif (test $1 = 0) then - rm -f ../$file fi done - if (test $1 = 1) then cp thr_data.h .. @@ -43,4 +40,4 @@ elif (test $1 = 0) then rm -f ../pair_lj_charmm_coul_pppm_omp.h rm -f ../pair_lj_charmm_coul_pppm_omp.cpp -fi +fi \ No newline at end of file diff --git a/src/USER-OMP/Package.sh b/src/USER-OMP/Package.sh index 5777ce381b..89c13bf570 100644 --- a/src/USER-OMP/Package.sh +++ b/src/USER-OMP/Package.sh @@ -1,4 +1,3 @@ -#/bin/sh # Update package files in LAMMPS # copy package file to src if it doesn't exists or is different # do not copy OpenMP style files, if a non-OpenMP version does diff --git a/src/USER-OMP/README b/src/USER-OMP/README new file mode 100644 index 0000000000..b200fee478 --- /dev/null +++ b/src/USER-OMP/README @@ -0,0 +1,10 @@ +This package provides OpenMP multi-threading support and other +optimizations of various LAMMPS pair styles, dihedral styles, and fix +styles. + +See this section of the manual to get started: + +doc/Section_accelerate.html, sub-section 5.2 + +The person who created this package is Axel Kohlmeyer at Temple U +(akohlmey at gmail.com). Contact him directly if you have questions. diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp index e45cfe9d5d..0aa6429c24 100644 --- a/src/USER-OMP/dihedral_helix_omp.cpp +++ b/src/USER-OMP/dihedral_helix_omp.cpp @@ -25,9 +25,11 @@ #include "domain.h" #include "force.h" #include "update.h" +#include "math_const.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 0.05 #define SMALL 0.001 @@ -209,10 +211,10 @@ void DihedralHelixOMP::eval(int nfrom, int nto, ThrData * const thr) siinv = 1.0/si; pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + - cphi[type]*sin(phi + 0.25*PI)*siinv; + cphi[type]*sin(phi + MY_PI4)*siinv; if (EFLAG) edihedral = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) + - cphi[type]*(1.0 + cos(phi + 0.25*PI)); + cphi[type]*(1.0 + cos(phi + MY_PI4)); a = pd; c = c * a; diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp index 760bd4912d..c387bee7bd 100644 --- a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp +++ b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp @@ -174,7 +174,6 @@ void DihedralMultiHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr) if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) { int me = comm->me; - if (screen) { char str[128]; sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d", diff --git a/src/angle.cpp b/src/angle.cpp index 334f26610b..54a3a5d051 100644 --- a/src/angle.cpp +++ b/src/angle.cpp @@ -16,10 +16,12 @@ #include "atom.h" #include "comm.h" #include "force.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -28,8 +30,6 @@ Angle::Angle(LAMMPS *lmp) : Pointers(lmp) energy = 0.0; allocated = 0; - PI = 4.0*atan(1.0); - THIRD = 1.0/3.0; maxeatom = maxvatom = 0; eatom = NULL; diff --git a/src/angle.h b/src/angle.h index 07a3064b4e..46ee5e1dc6 100644 --- a/src/angle.h +++ b/src/angle.h @@ -41,8 +41,6 @@ class Angle : protected Pointers { virtual double memory_usage(); protected: - double PI,THIRD; - int evflag; int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; diff --git a/src/atom.cpp b/src/atom.cpp index f42b1250f1..023d7a173f 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -75,7 +75,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) radius = rmass = NULL; vfrac = s0 = NULL; x0 = NULL; - ellipsoid = NULL; + ellipsoid = line = tri = NULL; spin = NULL; eradius = ervel = erforce = NULL; cs = csforce = vforce = ervelforce = NULL; @@ -106,7 +106,8 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) // initialize atom style and array existence flags // customize by adding new flag - sphere_flag = ellipsoid_flag = peri_flag = electron_flag = 0; + sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0; + peri_flag = electron_flag = 0; wavepacket_flag = sph_flag = 0; molecule_flag = q_flag = mu_flag = 0; @@ -185,6 +186,8 @@ Atom::~Atom() memory->destroy(s0); memory->destroy(x0); memory->destroy(ellipsoid); + memory->destroy(line); + memory->destroy(tri); memory->destroy(spin); memory->destroy(eradius); memory->destroy(ervel); @@ -259,8 +262,9 @@ void Atom::create_avec(const char *style, int narg, char **arg, char *suffix) // may have been set by old avec // customize by adding new flag - sphere_flag = ellipsoid_flag = peri_flag = electron_flag = 0; - + sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0; + peri_flag = electron_flag = 0; + molecule_flag = q_flag = mu_flag = 0; rmass_flag = radius_flag = omega_flag = torque_flag = angmom_flag = 0; vfrac_flag = spin_flag = eradius_flag = ervel_flag = erforce_flag = 0; diff --git a/src/atom.h b/src/atom.h index 98b687ec9a..429aacb1c2 100644 --- a/src/atom.h +++ b/src/atom.h @@ -51,7 +51,7 @@ class Atom : protected Pointers { double **omega,**angmom,**torque; double *radius,*rmass,*vfrac,*s0; double **x0; - int *ellipsoid; + int *ellipsoid,*line,*tri; int *spin; double *eradius,*ervel,*erforce,*ervelforce; double *cs,*csforce,*vforce; @@ -84,7 +84,7 @@ class Atom : protected Pointers { // atom style and per-atom array existence flags // customize by adding new flag - int sphere_flag,ellipsoid_flag,peri_flag,electron_flag; + int sphere_flag,ellipsoid_flag,line_flag,tri_flag,peri_flag,electron_flag; int wavepacket_flag,sph_flag; int molecule_flag,q_flag,mu_flag; diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index 47c9ef97f6..4baff5b602 100644 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -25,10 +25,12 @@ #include "domain.h" #include "modify.h" #include "fix.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 #define DELTA_BONUS 10000 @@ -53,8 +55,6 @@ AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp, int narg, char **arg) : atom->ellipsoid_flag = 1; atom->rmass_flag = atom->angmom_flag = atom->torque_flag = 1; - PI = 4.0*atan(1.0); - nlocal_bonus = nghost_bonus = nmax_bonus = 0; bonus = NULL; } @@ -1200,7 +1200,7 @@ void AtomVecEllipsoid::data_atom_bonus(int m, char **values) // reset ellipsoid mass // previously stored density in rmass - rmass[m] *= 4.0*PI/3.0 * shape[0]*shape[1]*shape[2]; + rmass[m] *= 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2]; bonus[nlocal_bonus].ilocal = m; ellipsoid[m] = nlocal_bonus++; diff --git a/src/atom_vec_ellipsoid.h b/src/atom_vec_ellipsoid.h index 537f1eaab7..0020eb5f28 100755 --- a/src/atom_vec_ellipsoid.h +++ b/src/atom_vec_ellipsoid.h @@ -76,7 +76,6 @@ class AtomVecEllipsoid : public AtomVec { void set_shape(int, double, double, double); private: - double PI; int *tag,*type,*mask,*image; double **x,**v,**f; double *rmass; diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp new file mode 100644 index 0000000000..ebf8b7d7a8 --- /dev/null +++ b/src/atom_vec_line.cpp @@ -0,0 +1,1167 @@ +/* ---------------------------------------------------------------------- + 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 "lmptype.h" +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "atom_vec_line.h" +#include "atom.h" +#include "domain.h" +#include "modify.h" +#include "force.h" +#include "fix.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 +#define DELTA_BONUS 10000 +#define EPSILON 0.001 + +/* ---------------------------------------------------------------------- */ + +AtomVecLine::AtomVecLine(LAMMPS *lmp, int narg, char **arg) : + AtomVec(lmp, narg, arg) +{ + molecular = 0; + + comm_x_only = comm_f_only = 0; + size_forward = 4; + size_reverse = 6; + size_border = 10; + size_velocity = 6; + size_data_atom = 8; + size_data_vel = 7; + size_data_bonus = 5; + xcol_data = 6; + + atom->line_flag = 1; + atom->molecule_flag = atom->rmass_flag = 1; + atom->omega_flag = atom->torque_flag = 1; + + nlocal_bonus = nghost_bonus = nmax_bonus = 0; + bonus = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecLine::~AtomVecLine() +{ + memory->sfree(bonus); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::init() +{ + AtomVec::init(); + + if (domain->dimension != 2) + error->all(FLERR,"Atom_style line can only be used in 2d simulations"); +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by DELTA + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecLine::grow(int n) +{ + if (n == 0) nmax += DELTA; + else nmax = n; + atom->nmax = nmax; + + 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,3,"atom:f"); + + molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); + rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); + omega = memory->grow(atom->omega,nmax,3,"atom:omega"); + torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + line = memory->grow(atom->line,nmax,"atom:line"); + + 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 AtomVecLine::grow_reset() +{ + tag = atom->tag; type = atom->type; + mask = atom->mask; image = atom->image; + x = atom->x; v = atom->v; f = atom->f; + molecule = atom->molecule; rmass = atom->rmass; + omega = atom->omega; torque = atom->torque; +} + +/* ---------------------------------------------------------------------- + grow bonus data structure +------------------------------------------------------------------------- */ + +void AtomVecLine::grow_bonus() +{ + nmax_bonus += DELTA_BONUS; + if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus), + "atom:bonus"); +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J +------------------------------------------------------------------------- */ + +void AtomVecLine::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]; + + molecule[j] = molecule[i]; + rmass[j] = rmass[i]; + omega[j][0] = omega[i][0]; + omega[j][1] = omega[i][1]; + omega[j][2] = omega[i][2]; + + // if delflag and atom J has bonus data, then delete it + + if (delflag && line[j] >= 0) { + copy_bonus(nlocal_bonus-1,line[j]); + nlocal_bonus--; + } + + // if atom I has bonus data and not deleting I, repoint I's bonus to J + + if (line[i] >= 0 && i != j) bonus[line[i]].ilocal = j; + line[j] = line[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j); +} + +/* ---------------------------------------------------------------------- + copy bonus data from I to J, effectively deleting the J entry + insure index pointers between per-atom and bonus data are updated +------------------------------------------------------------------------- */ + +void AtomVecLine::copy_bonus(int i, int j) +{ + memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); + line[bonus[j].ilocal] = j; +} + +/* ---------------------------------------------------------------------- + clear ghost info in bonus data + called before ghosts are recommunicated in comm and irregular +------------------------------------------------------------------------- */ + +void AtomVecLine::clear_bonus() +{ + nghost_bonus = 0; +} + +/* ---------------------------------------------------------------------- + set length value in bonus data for particle I + oriented along x axis + this may create or delete entry in bonus data +------------------------------------------------------------------------- */ + +void AtomVecLine::set_length(int i, double value) +{ + if (line[i] < 0) { + if (value == 0.0) return; + if (nlocal_bonus == nmax_bonus) grow_bonus(); + bonus[nlocal_bonus].length = value; + bonus[nlocal_bonus].theta = 0.0; + bonus[nlocal_bonus].ilocal = i; + line[i] = nlocal_bonus++; + } else if (value == 0.0) { + copy_bonus(nlocal_bonus-1,line[i]); + nlocal_bonus--; + line[i] = -1; + } else bonus[line[i]].length = value; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::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++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + } + } 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; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::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++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[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; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[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 (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + 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++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_comm_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::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++]; + if (line[i] >= 0) bonus[line[i]].theta = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::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++]; + if (line[i] >= 0) bonus[line[i]].theta = buf[m++]; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + omega[i][0] = buf[m++]; + omega[i][1] = buf[m++]; + omega[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::unpack_comm_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + if (line[i] >= 0) bonus[line[i]].theta = buf[m++]; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::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++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::pack_reverse_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::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++]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::unpack_reverse_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + } + } 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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + 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++] = omega[j][0]; + buf[m++] = omega[j][1]; + buf[m++] = omega[j][2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::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++] = molecule[j]; + if (line[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + buf[m++] = bonus[line[j]].length; + buf[m++] = bonus[line[j]].theta; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::unpack_border(int n, int first, double *buf) +{ + int i,j,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] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + line[i] = static_cast (buf[m++]); + if (line[i] == 0) line[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + bonus[j].length = buf[m++]; + bonus[j].theta = buf[m++]; + bonus[j].ilocal = i; + line[i] = j; + nghost_bonus++; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecLine::unpack_border_vel(int n, int first, double *buf) +{ + int i,j,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] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + line[i] = static_cast (buf[m++]); + if (line[i] == 0) line[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + bonus[j].length = buf[m++]; + bonus[j].theta = buf[m++]; + bonus[j].ilocal = i; + line[i] = j; + nghost_bonus++; + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + omega[i][0] = buf[m++]; + omega[i][1] = buf[m++]; + omega[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecLine::unpack_border_hybrid(int n, int first, double *buf) +{ + int i,j,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + molecule[i] = static_cast (buf[m++]); + line[i] = static_cast (buf[m++]); + if (line[i] == 0) line[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + bonus[j].length = buf[m++]; + bonus[j].theta = buf[m++]; + bonus[j].ilocal = i; + line[i] = j; + nghost_bonus++; + } + } + return 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 AtomVecLine::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++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = omega[i][0]; + buf[m++] = omega[i][1]; + buf[m++] = omega[i][2]; + + if (line[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = line[i]; + buf[m++] = bonus[j].length; + buf[m++] = bonus[j].theta; + } + + 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 AtomVecLine::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] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + omega[nlocal][0] = buf[m++]; + omega[nlocal][1] = buf[m++]; + omega[nlocal][2] = buf[m++]; + + line[nlocal] = static_cast (buf[m++]); + if (line[nlocal] == 0) line[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + bonus[nlocal_bonus].length = buf[m++]; + bonus[nlocal_bonus].theta = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + line[nlocal] = nlocal_bonus++; + } + + 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 AtomVecLine::size_restart() +{ + int i; + + int n = 0; + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (line[i] >= 0) n += 19; + else n += 17; + + 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 AtomVecLine::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++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = omega[i][0]; + buf[m++] = omega[i][1]; + buf[m++] = omega[i][2]; + + if (line[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = line[i]; + buf[m++] = bonus[j].length; + buf[m++] = bonus[j].theta; + } + + 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 AtomVecLine::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] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + omega[nlocal][0] = buf[m++]; + omega[nlocal][1] = buf[m++]; + omega[nlocal][2] = buf[m++]; + + line[nlocal] = static_cast (buf[m++]); + if (line[nlocal] == 0) line[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + bonus[nlocal_bonus].length = buf[m++]; + bonus[nlocal_bonus].theta = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + line[nlocal] = nlocal_bonus++; + } + + 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 AtomVecLine::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] = (512 << 20) | (512 << 10) | 512; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + molecule[nlocal] = 0; + rmass[nlocal] = 1.0; + omega[nlocal][0] = 0.0; + omega[nlocal][1] = 0.0; + omega[nlocal][2] = 0.0; + line[nlocal] = -1; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecLine::data_atom(double *coord, int imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = atoi(values[0]); + if (tag[nlocal] <= 0) + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); + + molecule[nlocal] = atoi(values[1]); + + type[nlocal] = atoi(values[2]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + line[nlocal] = atoi(values[3]); + if (line[nlocal] == 0) line[nlocal] = -1; + else if (line[nlocal] == 1) line[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[4]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density 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; + omega[nlocal][0] = 0.0; + omega[nlocal][1] = 0.0; + omega[nlocal][2] = 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 AtomVecLine::data_atom_hybrid(int nlocal, char **values) +{ + molecule[nlocal] = atoi(values[0]); + + line[nlocal] = atoi(values[1]); + if (line[nlocal] == 0) line[nlocal] = -1; + else if (line[nlocal] == 1) line[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[2]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + return 3; +} + +/* ---------------------------------------------------------------------- + unpack one line from Lines section of data file +------------------------------------------------------------------------- */ + +void AtomVecLine::data_atom_bonus(int m, char **values) +{ + if (line[m]) error->one(FLERR,"Assigning line parameters to non-line atom"); + + if (nlocal_bonus == nmax_bonus) grow_bonus(); + + double x1 = atof(values[0]); + double y1 = atof(values[1]); + double x2 = atof(values[2]); + double y2 = atof(values[3]); + double dx = x2 - x1; + double dy = y2 - y1; + double length = sqrt(dx*dx + dy*dy); + + bonus[nlocal_bonus].length = length; + if (dy >= 0.0) bonus[nlocal_bonus].theta = acos(dx/length); + else bonus[nlocal_bonus].theta = -acos(dx/length); + + double xc = 0.5*(x1+x2); + double yc = 0.5*(y1+y2); + dx = xc - x[m][0]; + dy = yc - x[m][1]; + double delta = sqrt(dx*dx + dy*dy); + + if (delta/length > EPSILON) + error->one(FLERR,"Inconsistent line segment in data file"); + + x[m][0] = xc; + x[m][1] = yc; + + // reset line mass + // previously stored density in rmass + + rmass[m] *= length; + + bonus[nlocal_bonus].ilocal = m; + line[m] = nlocal_bonus++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Velocities section of data file +------------------------------------------------------------------------- */ + +void AtomVecLine::data_vel(int m, char **values) +{ + v[m][0] = atof(values[0]); + v[m][1] = atof(values[1]); + v[m][2] = atof(values[2]); + omega[m][0] = atof(values[3]); + omega[m][1] = atof(values[4]); + omega[m][2] = atof(values[5]); +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one line in Velocities section of data file +------------------------------------------------------------------------- */ + +int AtomVecLine::data_vel_hybrid(int m, char **values) +{ + omega[m][0] = atof(values[0]); + omega[m][1] = atof(values[1]); + omega[m][2] = atof(values[2]); + return 3; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecLine::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,3); + + if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); + if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); + if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("line")) bytes += memory->usage(line,nmax); + + bytes += nmax_bonus*sizeof(Bonus); + + return bytes; +} + +/* ---------------------------------------------------------------------- + check consistency of internal Bonus data structure + n = # of atoms in regular structure to check against +------------------------------------------------------------------------- */ + +/* +void AtomVecLine::consistency_check(int n, char *str) +{ + int iflag = 0; + int count = 0; + for (int i = 0; i < n; i++) { + + if (line[i] >= 0) { + count++; + if (line[i] >= nlocal_bonus) iflag++; + if (bonus[line[i]].ilocal != i) iflag++; + //if (comm->me == 1 && update->ntimestep == 873) + // printf("CCHK %s: %d %d: %d %d: %d %d\n", + // str,i,n,line[i],nlocal_bonus,bonus[line[i]].ilocal,iflag); + } + } + + if (iflag) { + char msg[128]; + sprintf(msg,"BAD VECLINE PTRS: %s: %d %d: %d\n",str,comm->me, + update->ntimestep,iflag); + error->one(FLERR,msg); + } + + if (count != nlocal_bonus) { + char msg[128]; + sprintf(msg,"BAD VECLINE COUNT: %s: %d %d: %d %d\n", + str,comm->me,update->ntimestep,count,nlocal_bonus); + error->one(FLERR,msg); + } +} +*/ diff --git a/src/atom_vec_line.h b/src/atom_vec_line.h new file mode 100644 index 0000000000..3dd6d6e37c --- /dev/null +++ b/src/atom_vec_line.h @@ -0,0 +1,96 @@ +/* ---------------------------------------------------------------------- + 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(line,AtomVecLine) + +#else + +#ifndef LMP_ATOM_VEC_LINE_H +#define LMP_ATOM_VEC_LINE_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecLine : public AtomVec { + public: + struct Bonus { + double length,theta; + int ilocal; + }; + struct Bonus *bonus; + + AtomVecLine(class LAMMPS *, int, char **); + ~AtomVecLine(); + void init(); + void grow(int); + void grow_reset(); + 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 *); + int pack_reverse_hybrid(int, int, double *); + void unpack_reverse(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 *); + 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 *, int, char **); + int data_atom_hybrid(int, char **); + void data_vel(int, char **); + int data_vel_hybrid(int, char **); + bigint memory_usage(); + + // manipulate Bonus data structure for extra atom info + + void clear_bonus(); + void data_atom_bonus(int, char **); + + // unique to AtomVecLine + + void set_length(int, double); + + private: + int *tag,*type,*mask,*image; + double **x,**v,**f; + int *molecule; + double *rmass; + double **omega,**torque; + int *line; + + int nlocal_bonus,nghost_bonus,nmax_bonus; + + void grow_bonus(); + void copy_bonus(int, int); + // void consistency_check(int, char *); +}; + +} + +#endif +#endif diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index a3e2c34772..96b2d766d8 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -23,10 +23,12 @@ #include "force.h" #include "fix.h" #include "fix_adapt.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 @@ -50,8 +52,6 @@ AtomVecSphere::AtomVecSphere(LAMMPS *lmp, int narg, char **arg) : atom->sphere_flag = 1; atom->radius_flag = atom->rmass_flag = atom->omega_flag = atom->torque_flag = 1; - - PI = 4.0*atan(1.0); } /* ---------------------------------------------------------------------- */ @@ -929,7 +929,7 @@ void AtomVecSphere::create_atom(int itype, double *coord) v[nlocal][2] = 0.0; radius[nlocal] = 0.5; - rmass[nlocal] = 4.0*PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal]; + rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal]; omega[nlocal][0] = 0.0; omega[nlocal][1] = 0.0; omega[nlocal][2] = 0.0; @@ -965,7 +965,7 @@ void AtomVecSphere::data_atom(double *coord, int imagetmp, char **values) if (radius[nlocal] == 0.0) rmass[nlocal] = density; else - rmass[nlocal] = 4.0*PI/3.0 * + rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal] * density; x[nlocal][0] = coord[0]; @@ -1002,7 +1002,7 @@ int AtomVecSphere::data_atom_hybrid(int nlocal, char **values) if (radius[nlocal] == 0.0) rmass[nlocal] = density; else - rmass[nlocal] = 4.0*PI/3.0 * + rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal] * density; return 2; diff --git a/src/atom_vec_sphere.h b/src/atom_vec_sphere.h index 8157029615..78357b7d1a 100644 --- a/src/atom_vec_sphere.h +++ b/src/atom_vec_sphere.h @@ -61,7 +61,6 @@ class AtomVecSphere : public AtomVec { bigint memory_usage(); private: - double PI; int *tag,*type,*mask,*image; double **x,**v,**f; double *radius,*density,*rmass; diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp new file mode 100644 index 0000000000..03aed7aa65 --- /dev/null +++ b/src/atom_vec_tri.cpp @@ -0,0 +1,1561 @@ +/* ---------------------------------------------------------------------- + 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 "lmptype.h" +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "atom_vec_tri.h" +#include "math_extra.h" +#include "atom.h" +#include "domain.h" +#include "modify.h" +#include "force.h" +#include "fix.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 +#define DELTA_BONUS 10000 +#define EPSILON 0.001 + +/* ---------------------------------------------------------------------- */ + +AtomVecTri::AtomVecTri(LAMMPS *lmp, int narg, char **arg) : + AtomVec(lmp, narg, arg) +{ + molecular = 0; + + comm_x_only = comm_f_only = 0; + size_forward = 7; + size_reverse = 6; + size_border = 24; + size_velocity = 6; + size_data_atom = 8; + size_data_vel = 7; + size_data_bonus = 10; + xcol_data = 6; + + atom->tri_flag = 1; + atom->molecule_flag = atom->rmass_flag = 1; + atom->angmom_flag = atom->torque_flag = 1; + + nlocal_bonus = nghost_bonus = nmax_bonus = 0; + bonus = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecTri::~AtomVecTri() +{ + memory->sfree(bonus); +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::init() +{ + AtomVec::init(); + + if (domain->dimension != 3) + error->all(FLERR,"Atom_style tri can only be used in 3d simulations"); +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by DELTA + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecTri::grow(int n) +{ + if (n == 0) nmax += DELTA; + else nmax = n; + atom->nmax = nmax; + + 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,3,"atom:f"); + + molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); + rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); + angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom"); + torque = memory->grow(atom->torque,nmax,3,"atom:torque"); + tri = memory->grow(atom->tri,nmax,"atom:tri"); + + 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 AtomVecTri::grow_reset() +{ + tag = atom->tag; type = atom->type; + mask = atom->mask; image = atom->image; + x = atom->x; v = atom->v; f = atom->f; + molecule = atom->molecule; rmass = atom->rmass; + angmom = atom->angmom; torque = atom->torque; +} + +/* ---------------------------------------------------------------------- + grow bonus data structure +------------------------------------------------------------------------- */ + +void AtomVecTri::grow_bonus() +{ + nmax_bonus += DELTA_BONUS; + if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus), + "atom:bonus"); +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J + if delflag and atom J has bonus data, then delete it +------------------------------------------------------------------------- */ + +void AtomVecTri::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]; + + molecule[j] = molecule[i]; + rmass[j] = rmass[i]; + angmom[j][0] = angmom[i][0]; + angmom[j][1] = angmom[i][1]; + angmom[j][2] = angmom[i][2]; + + // if delflag and atom J has bonus data, then delete it + + if (delflag && tri[j] >= 0) { + copy_bonus(nlocal_bonus-1,tri[j]); + nlocal_bonus--; + } + + // if atom I has bonus data and not deleting I, repoint I's bonus to J + + if (tri[i] >= 0 && i != j) bonus[tri[i]].ilocal = j; + tri[j] = tri[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j); +} + +/* ---------------------------------------------------------------------- + copy bonus data from I to J, effectively deleting the J entry + insure index pointers between per-atom and bonus data are updated +------------------------------------------------------------------------- */ + +void AtomVecTri::copy_bonus(int i, int j) +{ + memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); + tri[bonus[j].ilocal] = j; +} + +/* ---------------------------------------------------------------------- + clear ghost info in bonus data + called before ghosts are recommunicated in comm and irregular +------------------------------------------------------------------------- */ + +void AtomVecTri::clear_bonus() +{ + nghost_bonus = 0; +} + +/* ---------------------------------------------------------------------- + set equilateral tri of size in bonus data for particle I + oriented symmetrically in xy plane + this may create or delete entry in bonus data +------------------------------------------------------------------------- */ + +void AtomVecTri::set_equilateral(int i, double size) +{ + if (tri[i] < 0) { + if (size == 0.0) return; + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *c1 = bonus[nlocal_bonus].c1; + double *c2 = bonus[nlocal_bonus].c2; + double *c3 = bonus[nlocal_bonus].c3; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = 1.0; + quat[1] = 0.0; + quat[2] = 0.0; + quat[3] = 0.0; + c1[0] = -size/2.0; + c1[1] = -sqrt(3.0)/2.0 * size / 3.0; + c1[2] = 0.0; + c2[0] = size/2.0; + c2[1] = -sqrt(3.0)/2.0 * size / 3.0; + c2[2] = 0.0; + c3[0] = 0.0; + c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0; + c3[2] = 0.0; + inertia[0] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[1] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[2] = sqrt(3.0)/48.0 * size*size*size*size; + bonus[nlocal_bonus].ilocal = i; + tri[i] = nlocal_bonus++; + } else if (size == 0.0) { + copy_bonus(nlocal_bonus-1,tri[i]); + nlocal_bonus--; + tri[i] = -1; + } else { + double *c1 = bonus[tri[i]].c1; + double *c2 = bonus[tri[i]].c2; + double *c3 = bonus[tri[i]].c3; + double *inertia = bonus[tri[i]].inertia; + c1[0] = -size/2.0; + c1[1] = -sqrt(3.0)/2.0 * size / 3.0; + c1[2] = 0.0; + c2[0] = size/2.0; + c2[1] = -sqrt(3.0)/2.0 * size / 3.0; + c2[2] = 0.0; + c3[0] = 0.0; + c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0; + c3[2] = 0.0; + inertia[0] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[1] = sqrt(3.0)/96.0 * size*size*size*size; + inertia[2] = sqrt(3.0)/48.0 * size*size*size*size; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + double *quat; + + 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]; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[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; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::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; + double *quat; + + 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]; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = 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++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = 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++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + 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++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_comm_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + double *quat; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + if (tri[j] >= 0) { + quat = bonus[tri[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + 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++]; + if (tri[i] >= 0) { + quat = bonus[tri[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + 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++]; + if (tri[i] >= 0) { + quat = bonus[tri[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + angmom[i][0] = buf[m++]; + angmom[i][1] = buf[m++]; + angmom[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::unpack_comm_hybrid(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + if (tri[i] >= 0) { + quat = bonus[tri[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::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++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_reverse_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::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++]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::unpack_reverse_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + double *quat,*c1,*c2,*c3,*inertia; + + 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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::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; + double *quat,*c1,*c2,*c3,*inertia; + + 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++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = 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++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = 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++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + 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++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::pack_border_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = molecule[j]; + if (tri[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[tri[j]].quat; + c1 = bonus[tri[j]].c1; + c2 = bonus[tri[j]].c2; + c3 = bonus[tri[j]].c3; + inertia = bonus[tri[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_border(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + 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] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + tri[i] = static_cast (buf[m++]); + if (tri[i] == 0) tri[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + c1 = bonus[j].c1; + c2 = bonus[j].c2; + c3 = bonus[j].c3; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ilocal = i; + tri[i] = j; + nghost_bonus++; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecTri::unpack_border_vel(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + 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] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + molecule[i] = static_cast (buf[m++]); + tri[i] = static_cast (buf[m++]); + if (tri[i] == 0) tri[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + c1 = bonus[j].c1; + c2 = bonus[j].c2; + c3 = bonus[j].c3; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ilocal = i; + tri[i] = j; + nghost_bonus++; + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + angmom[i][0] = buf[m++]; + angmom[i][1] = buf[m++]; + angmom[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecTri::unpack_border_hybrid(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + molecule[i] = static_cast (buf[m++]); + tri[i] = static_cast (buf[m++]); + if (tri[i] == 0) tri[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + c1 = bonus[j].c1; + c2 = bonus[j].c2; + c3 = bonus[j].c3; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ilocal = i; + tri[i] = j; + nghost_bonus++; + } + } + return 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 AtomVecTri::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++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = angmom[i][0]; + buf[m++] = angmom[i][1]; + buf[m++] = angmom[i][2]; + + if (tri[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = tri[i]; + double *quat = bonus[j].quat; + double *c1 = bonus[j].c1; + double *c2 = bonus[j].c2; + double *c3 = bonus[j].c3; + double *inertia = bonus[j].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[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 AtomVecTri::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] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + angmom[nlocal][0] = buf[m++]; + angmom[nlocal][1] = buf[m++]; + angmom[nlocal][2] = buf[m++]; + + tri[nlocal] = static_cast (buf[m++]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *c1 = bonus[nlocal_bonus].c1; + double *c2 = bonus[nlocal_bonus].c2; + double *c3 = bonus[nlocal_bonus].c3; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + tri[nlocal] = nlocal_bonus++; + } + + 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 AtomVecTri::size_restart() +{ + int i; + + int n = 0; + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (tri[i] >= 0) n += 33; + else n += 17; + + 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 AtomVecTri::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++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + buf[m++] = image[i]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + + buf[m++] = molecule[i]; + buf[m++] = rmass[i]; + buf[m++] = angmom[i][0]; + buf[m++] = angmom[i][1]; + buf[m++] = angmom[i][2]; + + if (tri[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = tri[i]; + double *quat = bonus[j].quat; + double *c1 = bonus[j].c1; + double *c2 = bonus[j].c2; + double *c3 = bonus[j].c3; + double *inertia = bonus[j].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = c1[0]; + buf[m++] = c1[1]; + buf[m++] = c1[2]; + buf[m++] = c2[0]; + buf[m++] = c2[1]; + buf[m++] = c2[2]; + buf[m++] = c3[0]; + buf[m++] = c3[1]; + buf[m++] = c3[2]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[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 AtomVecTri::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] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = static_cast (buf[m++]); + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + + molecule[nlocal] = static_cast (buf[m++]); + rmass[nlocal] = buf[m++]; + angmom[nlocal][0] = buf[m++]; + angmom[nlocal][1] = buf[m++]; + angmom[nlocal][2] = buf[m++]; + + tri[nlocal] = static_cast (buf[m++]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *c1 = bonus[nlocal_bonus].c1; + double *c2 = bonus[nlocal_bonus].c2; + double *c3 = bonus[nlocal_bonus].c3; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + c1[0] = buf[m++]; + c1[1] = buf[m++]; + c1[2] = buf[m++]; + c2[0] = buf[m++]; + c2[1] = buf[m++]; + c2[2] = buf[m++]; + c3[0] = buf[m++]; + c3[1] = buf[m++]; + c3[2] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[nlocal_bonus].ilocal = nlocal; + tri[nlocal] = nlocal_bonus++; + } + + 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 AtomVecTri::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] = (512 << 20) | (512 << 10) | 512; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + molecule[nlocal] = 0; + rmass[nlocal] = 1.0; + angmom[nlocal][0] = 0.0; + angmom[nlocal][1] = 0.0; + angmom[nlocal][2] = 0.0; + tri[nlocal] = -1; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one tri from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecTri::data_atom(double *coord, int imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = atoi(values[0]); + if (tag[nlocal] <= 0) + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); + + molecule[nlocal] = atoi(values[1]); + + type[nlocal] = atoi(values[2]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + tri[nlocal] = atoi(values[3]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else if (tri[nlocal] == 1) tri[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[4]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density 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; + angmom[nlocal][0] = 0.0; + angmom[nlocal][1] = 0.0; + angmom[nlocal][2] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one tri in Atoms section of data file + initialize other atom quantities for this sub-style +------------------------------------------------------------------------- */ + +int AtomVecTri::data_atom_hybrid(int nlocal, char **values) +{ + molecule[nlocal] = atoi(values[0]); + + tri[nlocal] = atoi(values[1]); + if (tri[nlocal] == 0) tri[nlocal] = -1; + else if (tri[nlocal] == 1) tri[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[2]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + return 3; +} + +/* ---------------------------------------------------------------------- + unpack one tri from Tris section of data file +------------------------------------------------------------------------- */ + +void AtomVecTri::data_atom_bonus(int m, char **values) +{ + if (tri[m]) error->one(FLERR,"Assigning tri parameters to non-tri atom"); + + if (nlocal_bonus == nmax_bonus) grow_bonus(); + + double c1[3],c2[3],c3[3]; + c1[0] = atof(values[0]); + c1[1] = atof(values[1]); + c1[2] = atof(values[2]); + c2[0] = atof(values[3]); + c2[1] = atof(values[4]); + c2[2] = atof(values[5]); + c3[0] = atof(values[6]); + c3[1] = atof(values[7]); + c3[2] = atof(values[8]); + + // check for duplicate points + + if (c1[0] == c2[0] && c1[1] == c2[1] && c1[2] == c2[2]) + error->one(FLERR,"Invalid shape in Triangles section of data file"); + if (c1[0] == c3[0] && c1[1] == c3[1] && c1[2] == c3[2]) + error->one(FLERR,"Invalid shape in Triangles section of data file"); + if (c2[0] == c3[0] && c2[1] == c3[1] && c2[2] == c3[2]) + error->one(FLERR,"Invalid shape in Triangles section of data file"); + + // size = length of one edge + + double c2mc1[2],c3mc1[3]; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + double size = MAX(MathExtra::len3(c2mc1),MathExtra::len3(c3mc1)); + + // centroid = 1/3 of sum of vertices + + double centroid[3]; + centroid[0] = (c1[0]+c2[0]+c3[0]) / 3.0; + centroid[1] = (c1[1]+c2[1]+c3[1]) / 3.0; + centroid[2] = (c1[2]+c2[2]+c3[2]) / 3.0; + + double dx = centroid[0] - x[m][0]; + double dy = centroid[1] - x[m][1]; + double dz = centroid[2] - x[m][2]; + double delta = sqrt(dx*dx + dy*dy + dz*dz); + + if (delta/size > EPSILON) + error->one(FLERR,"Inconsistent triangle in data file"); + + x[m][0] = centroid[0]; + x[m][1] = centroid[1]; + x[m][2] = centroid[2]; + + // reset tri mass + // previously stored density in rmass + // tri area = 0.5 len(U x V), where U,V are edge vectors from one vertex + + double norm[3]; + MathExtra::cross3(c2mc1,c3mc1,norm); + double area = 0.5 * MathExtra::len3(norm); + rmass[m] *= area; + + // inertia = inertia tensor of triangle as 6-vector in Voigt notation + + double inertia[6]; + MathExtra::inertia_triangle(c1,c2,c3,rmass[m],inertia); + + // diagonalize inertia tensor via Jacobi rotations + // bonus[].inertia = 3 eigenvalues = principal moments of inertia + // evectors and exzy_space = 3 evectors = principal axes of triangle + + double tensor[3][3],evectors[3][3]; + tensor[0][0] = inertia[0]; + tensor[1][1] = inertia[1]; + tensor[2][2] = inertia[2]; + tensor[1][2] = tensor[2][1] = inertia[3]; + tensor[0][2] = tensor[2][0] = inertia[4]; + tensor[0][1] = tensor[1][0] = inertia[5]; + + int ierror = MathExtra::jacobi(tensor,bonus[nlocal_bonus].inertia,evectors); + if (ierror) error->one(FLERR,"Insufficient Jacobi rotations for triangle"); + + double ex_space[3],ey_space[3],ez_space[3]; + ex_space[0] = evectors[0][0]; + ex_space[1] = evectors[1][0]; + ex_space[2] = evectors[2][0]; + ey_space[0] = evectors[0][1]; + ey_space[1] = evectors[1][1]; + ey_space[2] = evectors[2][1]; + ez_space[0] = evectors[0][2]; + ez_space[1] = evectors[1][2]; + ez_space[2] = evectors[2][2]; + + // enforce 3 orthogonal vectors as a right-handed coordinate system + // flip 3rd vector if needed + + MathExtra::cross3(ex_space,ey_space,norm); + if (MathExtra::dot3(norm,ez_space) < 0.0) MathExtra::negate3(ez_space); + + // create initial quaternion + + MathExtra::exyz_to_q(ex_space,ey_space,ez_space,bonus[nlocal_bonus].quat); + + // bonus c1,c2,c3 = displacement of c1,c2,c3 from centroid + // in basis of principal axes + + double disp[3]; + MathExtra::sub3(c1,centroid,disp); + MathExtra::transpose_matvec(ex_space,ey_space,ez_space, + disp,bonus[nlocal_bonus].c1); + MathExtra::sub3(c2,centroid,disp); + MathExtra::transpose_matvec(ex_space,ey_space,ez_space, + disp,bonus[nlocal_bonus].c2); + MathExtra::sub3(c3,centroid,disp); + MathExtra::transpose_matvec(ex_space,ey_space,ez_space, + disp,bonus[nlocal_bonus].c3); + + bonus[nlocal_bonus].ilocal = m; + tri[m] = nlocal_bonus++; +} + +/* ---------------------------------------------------------------------- + unpack one tri from Velocities section of data file +------------------------------------------------------------------------- */ + +void AtomVecTri::data_vel(int m, char **values) +{ + v[m][0] = atof(values[0]); + v[m][1] = atof(values[1]); + v[m][2] = atof(values[2]); + angmom[m][0] = atof(values[3]); + angmom[m][1] = atof(values[4]); + angmom[m][2] = atof(values[5]); +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one tri in Velocities section of data file +------------------------------------------------------------------------- */ + +int AtomVecTri::data_vel_hybrid(int m, char **values) +{ + angmom[m][0] = atof(values[0]); + angmom[m][1] = atof(values[1]); + angmom[m][2] = atof(values[2]); + return 3; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecTri::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,3); + + if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); + if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); + if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3); + if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax,3); + if (atom->memcheck("tri")) bytes += memory->usage(tri,nmax); + + bytes += nmax_bonus*sizeof(Bonus); + + return bytes; +} diff --git a/src/atom_vec_tri.h b/src/atom_vec_tri.h new file mode 100644 index 0000000000..33f3e9cd6e --- /dev/null +++ b/src/atom_vec_tri.h @@ -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. +------------------------------------------------------------------------- */ + +#ifdef ATOM_CLASS + +AtomStyle(tri,AtomVecTri) + +#else + +#ifndef LMP_ATOM_VEC_TRI_H +#define LMP_ATOM_VEC_TRI_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecTri : public AtomVec { + public: + struct Bonus { + double quat[4]; + double c1[3],c2[3],c3[3]; + double inertia[3]; + int ilocal; + }; + struct Bonus *bonus; + + AtomVecTri(class LAMMPS *, int, char **); + ~AtomVecTri(); + void init(); + void grow(int); + void grow_reset(); + 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 *); + int pack_reverse_hybrid(int, int, double *); + void unpack_reverse(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 *); + 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 *, int, char **); + int data_atom_hybrid(int, char **); + void data_vel(int, char **); + int data_vel_hybrid(int, char **); + bigint memory_usage(); + + // manipulate Bonus data structure for extra atom info + + void clear_bonus(); + void data_atom_bonus(int, char **); + + // unique to AtomVecTri + + void set_equilateral(int, double); + + private: + int *tag,*type,*mask,*image; + double **x,**v,**f; + int *molecule; + double *rmass; + double **angmom,**torque; + int *tri; + + int nlocal_bonus,nghost_bonus,nmax_bonus; + + void grow_bonus(); + void copy_bonus(int, int); +}; + +} + +#endif +#endif diff --git a/src/compute_angle_local.cpp b/src/compute_angle_local.cpp index a126348d31..d19b7e71aa 100644 --- a/src/compute_angle_local.cpp +++ b/src/compute_angle_local.cpp @@ -20,10 +20,12 @@ #include "domain.h" #include "force.h" #include "angle.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 @@ -133,7 +135,6 @@ int ComputeAngleLocal::compute_angles(int flag) } Angle *angle = force->angle; - double PI = 4.0*atan(1.0); m = n = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { @@ -170,7 +171,7 @@ int ComputeAngleLocal::compute_angles(int flag) c /= r1*r2; if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; - tbuf[n] = 180.0*acos(c)/PI; + tbuf[n] = 180.0*acos(c)/MY_PI; } if (eflag >= 0) { diff --git a/src/compute_dihedral_local.cpp b/src/compute_dihedral_local.cpp index 6215346717..10cac6f607 100644 --- a/src/compute_dihedral_local.cpp +++ b/src/compute_dihedral_local.cpp @@ -20,10 +20,12 @@ #include "domain.h" #include "force.h" #include "dihedral.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 #define SMALL 0.001 @@ -128,8 +130,6 @@ int ComputeDihedralLocal::compute_dihedrals(int flag) } } - double PI = 4.0*atan(1.0); - m = n = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; @@ -190,7 +190,7 @@ int ComputeDihedralLocal::compute_dihedrals(int flag) if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; - pbuf[n] = 180.0*atan2(s,c)/PI; + pbuf[n] = 180.0*atan2(s,c)/MY_PI; } n += nvalues; } diff --git a/src/compute_improper_local.cpp b/src/compute_improper_local.cpp index 7162277c39..3285f2561c 100644 --- a/src/compute_improper_local.cpp +++ b/src/compute_improper_local.cpp @@ -20,10 +20,12 @@ #include "domain.h" #include "force.h" #include "improper.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 10000 @@ -129,8 +131,6 @@ int ComputeImproperLocal::compute_impropers(int flag) } } - double PI = 4.0*atan(1.0); - m = n = 0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; @@ -188,7 +188,7 @@ int ComputeImproperLocal::compute_impropers(int flag) if (c > 1.0) c = 1.0; if (c < -1.0) c = -1.0; - cbuf[n] = 180.0*acos(c)/PI; + cbuf[n] = 180.0*acos(c)/MY_PI; } n += nvalues; } diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index f7605d5552..80efd8a5bf 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -11,10 +11,14 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "math.h" #include "string.h" #include "compute_property_atom.h" +#include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "update.h" #include "domain.h" #include "memory.h" @@ -173,39 +177,39 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice[i] = &ComputePropertyAtom::pack_angmomz; } else if (strcmp(arg[iarg],"shapex") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapex; } else if (strcmp(arg[iarg],"shapey") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapey; } else if (strcmp(arg[iarg],"shapez") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_shapez; } else if (strcmp(arg[iarg],"quatw") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatw; } else if (strcmp(arg[iarg],"quati") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quati; } else if (strcmp(arg[iarg],"quatj") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatj; } else if (strcmp(arg[iarg],"quatk") == 0) { - avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - if (!avec) error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_quatk; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) @@ -244,6 +248,83 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : "atom property that isn't allocated"); pack_choice[i] = &ComputePropertyAtom::pack_erforce; + } else if (strcmp(arg[iarg],"end1x") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end1x; + } else if (strcmp(arg[iarg],"end1y") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end1y; + } else if (strcmp(arg[iarg],"end1z") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end1z; + } else if (strcmp(arg[iarg],"end2x") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end2x; + } else if (strcmp(arg[iarg],"end2y") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end2y; + } else if (strcmp(arg[iarg],"end2z") == 0) { + avec_line = (AtomVecLine *) atom->style_match("line"); + if (!avec_line) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_end2z; + + } else if (strcmp(arg[iarg],"corner1x") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner1x; + } else if (strcmp(arg[iarg],"corner1y") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner1y; + } else if (strcmp(arg[iarg],"corner1z") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner1z; + } else if (strcmp(arg[iarg],"corner2x") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner2x; + } else if (strcmp(arg[iarg],"corner2y") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner2y; + } else if (strcmp(arg[iarg],"corner2z") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner2z; + } else if (strcmp(arg[iarg],"corner3x") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner3x; + } else if (strcmp(arg[iarg],"corner3y") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner3y; + } else if (strcmp(arg[iarg],"corner3z") == 0) { + avec_tri = (AtomVecTri *) atom->style_match("tri"); + if (!avec_tri) error->all(FLERR,"Compute property/atom for " + "atom property that isn't allocated"); + pack_choice[i] = &ComputePropertyAtom::pack_corner3z; + } else error->all(FLERR,"Invalid keyword in compute property/atom command"); } @@ -994,7 +1075,7 @@ void ComputePropertyAtom::pack_angmomz(int n) void ComputePropertyAtom::pack_shapex(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1011,7 +1092,7 @@ void ComputePropertyAtom::pack_shapex(int n) void ComputePropertyAtom::pack_shapey(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1028,7 +1109,7 @@ void ComputePropertyAtom::pack_shapey(int n) void ComputePropertyAtom::pack_shapez(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1045,7 +1126,7 @@ void ComputePropertyAtom::pack_shapez(int n) void ComputePropertyAtom::pack_quatw(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1062,7 +1143,7 @@ void ComputePropertyAtom::pack_quatw(int n) void ComputePropertyAtom::pack_quati(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1079,7 +1160,7 @@ void ComputePropertyAtom::pack_quati(int n) void ComputePropertyAtom::pack_quatj(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1096,7 +1177,7 @@ void ComputePropertyAtom::pack_quatj(int n) void ComputePropertyAtom::pack_quatk(int n) { - AtomVecEllipsoid::Bonus *bonus = avec->bonus; + AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; @@ -1213,3 +1294,294 @@ void ComputePropertyAtom::pack_erforce(int n) n += nvalues; } } + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end1x(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][0] - 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end1y(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][1] - 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end1z(int n) +{ + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) buf[n] = x[i][2]; + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end2x(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][0] + 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end2y(int n) +{ + AtomVecLine::Bonus *bonus = avec_line->bonus; + int *line = atom->line; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && line[i] >= 0) + buf[n] = x[i][1] + 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta); + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_end2z(int n) +{ + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) buf[n] = x[i][2]; + else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner1x(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,c); + buf[n] = x[i][0] + c[0]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner1y(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,c); + buf[n] = x[i][1] + c[1]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner1z(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c1,c); + buf[n] = x[i][2] + c[2]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner2x(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c2,c); + buf[n] = x[i][0] + c[0]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner2y(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c2,c); + buf[n] = x[i][1] + c[1]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner2z(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c2,c); + buf[n] = x[i][2] + c[2]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner3x(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c3,c); + buf[n] = x[i][0] + c[0]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner3y(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c3,c); + buf[n] = x[i][1] + c[1]; + } else buf[n] = 0.0; + n += nvalues; + } +} + +/* ---------------------------------------------------------------------- */ + +void ComputePropertyAtom::pack_corner3z(int n) +{ + AtomVecTri::Bonus *bonus = avec_tri->bonus; + int *tri = atom->tri; + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + double p[3][3],c[3]; + for (int i = 0; i < nlocal; i++) { + if ((mask[i] & groupbit) && tri[i] >= 0) { + MathExtra::quat_to_mat(bonus[tri[i]].quat,p); + MathExtra::matvec(p,bonus[tri[i]].c3,c); + buf[n] = x[i][2] + c[2]; + } else buf[n] = 0.0; + n += nvalues; + } +} diff --git a/src/compute_property_atom.h b/src/compute_property_atom.h index b32d0a93df..8f675b6204 100644 --- a/src/compute_property_atom.h +++ b/src/compute_property_atom.h @@ -38,7 +38,9 @@ class ComputePropertyAtom : public Compute { double *vector; double **array; double *buf; - class AtomVecEllipsoid *avec; + class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; typedef void (ComputePropertyAtom::*FnPtrPack)(int); FnPtrPack *pack_choice; // ptrs to pack functions @@ -101,6 +103,21 @@ class ComputePropertyAtom : public Compute { void pack_eradius(int); void pack_ervel(int); void pack_erforce(int); + void pack_end1x(int); + void pack_end1y(int); + void pack_end1z(int); + void pack_end2x(int); + void pack_end2y(int); + void pack_end2z(int); + void pack_corner1x(int); + void pack_corner1y(int); + void pack_corner1z(int); + void pack_corner2x(int); + void pack_corner2y(int); + void pack_corner2z(int); + void pack_corner3x(int); + void pack_corner3y(int); + void pack_corner3z(int); }; } diff --git a/src/compute_rdf.cpp b/src/compute_rdf.cpp index 9dbe3aded0..31776f9473 100644 --- a/src/compute_rdf.cpp +++ b/src/compute_rdf.cpp @@ -28,10 +28,12 @@ #include "neigh_request.h" #include "neigh_list.h" #include "group.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -267,10 +269,9 @@ void ComputeRDF::compute_array() // assuming J atoms are at uniform density double constant,nideal,gr,ncoord,rlower,rupper; - double PI = 4.0*atan(1.0); if (domain->dimension == 3) { - constant = 4.0*PI / (3.0*domain->xprd*domain->yprd*domain->zprd); + constant = 4.0*MY_PI / (3.0*domain->xprd*domain->yprd*domain->zprd); for (m = 0; m < npairs; m++) { ncoord = 0.0; @@ -289,7 +290,7 @@ void ComputeRDF::compute_array() } } else { - constant = PI / (domain->xprd*domain->yprd); + constant = MY_PI / (domain->xprd*domain->yprd); for (m = 0; m < npairs; m++) { ncoord = 0.0; diff --git a/src/dihedral.cpp b/src/dihedral.cpp index d55c140e2d..f1a62cba16 100644 --- a/src/dihedral.cpp +++ b/src/dihedral.cpp @@ -32,7 +32,6 @@ Dihedral::Dihedral(LAMMPS *lmp) : Pointers(lmp) energy = 0.0; allocated = 0; - PI = 4.0*atan(1.0); maxeatom = maxvatom = 0; eatom = NULL; diff --git a/src/dihedral.h b/src/dihedral.h index c41cedad03..b41272b7ba 100644 --- a/src/dihedral.h +++ b/src/dihedral.h @@ -41,8 +41,6 @@ class Dihedral : protected Pointers { virtual double memory_usage(); protected: - double PI; - int evflag; int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; diff --git a/src/dump_image.cpp b/src/dump_image.cpp index 25dc36109f..16f677327e 100644 --- a/src/dump_image.cpp +++ b/src/dump_image.cpp @@ -30,6 +30,7 @@ #include "input.h" #include "variable.h" #include "random_mars.h" +#include "math_const.h" #include "error.h" #include "memory.h" @@ -38,6 +39,7 @@ #endif using namespace LAMMPS_NS; +using namespace MathConst; #define NCOLORS 140 #define NELEMENTS 109 @@ -57,8 +59,6 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : { if (binary || multiproc) error->all(FLERR,"Invalid dump image filename"); - PI = 4.0*atan(1.0); - // set filetype based on filename suffix int n = strlen(filename); @@ -95,8 +95,8 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : bdiamvalue = 0.5; } width = height = 512; - theta = 60.0 * PI/180.0; - phi = 30.0 * PI/180.0; + theta = 60.0 * MY_PI/180.0; + phi = 30.0 * MY_PI/180.0; thetastr = phistr = NULL; cflag = STATIC; cx = cy = cz = 0.5; @@ -171,7 +171,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : theta = atof(arg[iarg+1]); if (theta < 0.0 || theta > 180.0) error->all(FLERR,"Invalid dump image theta value"); - theta *= PI/180.0; + theta *= MY_PI/180.0; } if (strstr(arg[iarg+2],"v_") == arg[iarg+2]) { int n = strlen(&arg[iarg+2][2]) + 1; @@ -179,7 +179,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : strcpy(phistr,&arg[iarg+2][2]); } else { phi = atof(arg[iarg+2]); - phi *= PI/180.0; + phi *= MY_PI/180.0; } iarg += 3; @@ -358,25 +358,25 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : // static parameters - FOV = PI/6.0; // 30 degrees + FOV = MY_PI/6.0; // 30 degrees ambientColor[0] = 0.0; ambientColor[1] = 0.0; ambientColor[2] = 0.0; - keyLightPhi = -PI/4.0; // -45 degrees - keyLightTheta = PI/6.0; // 30 degrees + keyLightPhi = -MY_PI4; // -45 degrees + keyLightTheta = MY_PI/6.0; // 30 degrees keyLightColor[0] = 0.9; keyLightColor[1] = 0.9; keyLightColor[2] = 0.9; - fillLightPhi = PI/6.0; // 30 degrees + fillLightPhi = MY_PI/6.0; // 30 degrees fillLightTheta = 0; fillLightColor[0] = 0.45; fillLightColor[1] = 0.45; fillLightColor[2] = 0.45; - backLightPhi = PI; // 180 degrees - backLightTheta = PI/12.0; // 15 degrees + backLightPhi = MY_PI; // 180 degrees + backLightTheta = MY_PI/12.0; // 15 degrees backLightColor[0] = 0.9; backLightColor[1] = 0.9; backLightColor[2] = 0.9; @@ -676,11 +676,11 @@ void DumpImage::view_params() theta = input->variable->compute_equal(thetavar); if (theta < 0.0 || theta > 180.0) error->all(FLERR,"Invalid dump image theta value"); - theta *= PI/180.0; + theta *= MY_PI/180.0; } if (phistr) { phi = input->variable->compute_equal(phivar); - phi *= PI/180.0; + phi *= MY_PI/180.0; } camDir[0] = sin(theta)*cos(phi); @@ -764,7 +764,7 @@ void DumpImage::view_params() if (ssao) { SSAORadius = maxdel * 0.05 * ssaoint; SSAOSamples = static_cast (8.0 + 32.0*ssaoint); - SSAOJitter = PI / 12; + SSAOJitter = MY_PI / 12; ambientColor[0] = 0.5; ambientColor[1] = 0.5; ambientColor[2] = 0.5; @@ -1358,7 +1358,7 @@ void DumpImage::compute_SSAO() { // used for rasterizing the spheres - double delTheta = 2.0*PI / SSAOSamples; + double delTheta = 2.0*MY_PI / SSAOSamples; // typical neighborhood value for shading diff --git a/src/dump_image.h b/src/dump_image.h index 866fc32e89..844ba1c112 100644 --- a/src/dump_image.h +++ b/src/dump_image.h @@ -69,8 +69,6 @@ class DumpImage : public DumpCustom { // constant view params - double PI; - double FOV; double ambientColor[3]; diff --git a/src/fix_adapt.cpp b/src/fix_adapt.cpp index fd1a256b8a..59af597bc3 100644 --- a/src/fix_adapt.cpp +++ b/src/fix_adapt.cpp @@ -24,10 +24,12 @@ #include "kspace.h" #include "input.h" #include "variable.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{PAIR,KSPACE,ATOM}; enum{DIAMETER}; @@ -309,7 +311,6 @@ void FixAdapt::change_settings() if (ad->aparam == DIAMETER) { int mflag = 0; if (atom->rmass_flag) mflag = 1; - double PI = 4.0*atan(1.0); double density; double *radius = atom->radius; @@ -324,9 +325,11 @@ void FixAdapt::change_settings() } else { for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { - density = rmass[i] / (4.0*PI/3.0 * radius[i]*radius[i]*radius[i]); + density = rmass[i] / (4.0*MY_PI/3.0 * + radius[i]*radius[i]*radius[i]); radius[i] = 0.5*value; - rmass[i] = 4.0*PI/3.0 * radius[i]*radius[i]*radius[i] * density; + rmass[i] = 4.0*MY_PI/3.0 * + radius[i]*radius[i]*radius[i] * density; } } } diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp index 16a3c1feab..fee57525d8 100644 --- a/src/fix_addforce.cpp +++ b/src/fix_addforce.cpp @@ -137,28 +137,32 @@ void FixAddForce::init() if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (xvar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xstyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (yvar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; else if (input->variable->atomstyle(yvar)) ystyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (zvar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zstyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } if (estr) { evar = input->variable->find(estr); - if (evar < 0) error->all(FLERR,"Variable name for fix addforce does not exist"); + if (evar < 0) + error->all(FLERR,"Variable name for fix addforce does not exist"); if (input->variable->atomstyle(evar)) estyle = ATOM; else error->all(FLERR,"Variable for fix addforce is invalid style"); } else estyle = NONE; @@ -167,7 +171,8 @@ void FixAddForce::init() if (iregion >= 0) { iregion = domain->find_region(idregion); - if (iregion == -1) error->all(FLERR,"Region ID for fix addforce does not exist"); + if (iregion == -1) + error->all(FLERR,"Region ID for fix addforce does not exist"); } if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM) diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp index 039bba40b2..097683ad23 100644 --- a/src/fix_deform.cpp +++ b/src/fix_deform.cpp @@ -27,10 +27,12 @@ #include "lattice.h" #include "force.h" #include "modify.h" +#include "math_const.h" #include "kspace.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{NONE,FINAL,DELTA,SCALE,VEL,ERATE,TRATE,VOLUME,WIGGLE}; enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE}; @@ -305,7 +307,7 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) if (force_reneighbor) irregular = new Irregular(lmp); else irregular = NULL; - TWOPI = 8.0*atan(1.0); + TWOPI = 2.0*MY_PI; } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_gravity.cpp b/src/fix_gravity.cpp index 09a2e2c7f1..de71e6bd79 100644 --- a/src/fix_gravity.cpp +++ b/src/fix_gravity.cpp @@ -20,9 +20,11 @@ #include "update.h" #include "domain.h" #include "respa.h" +#include "math_const.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{CHUTE,SPHERICAL,GRADIENT,VECTOR}; @@ -65,8 +67,7 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) : zdir = atof(arg[7]); } else error->all(FLERR,"Illegal fix gravity command"); - double PI = 4.0*atan(1.0); - degree2rad = PI/180.0; + degree2rad = MY_PI/180.0; if (style == CHUTE || style == SPHERICAL || style == GRADIENT) { if (domain->dimension == 3) { diff --git a/src/fix_move.cpp b/src/fix_move.cpp index afd087772e..74657fa86e 100644 --- a/src/fix_move.cpp +++ b/src/fix_move.cpp @@ -26,10 +26,12 @@ #include "respa.h" #include "input.h" #include "variable.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{LINEAR,WIGGLE,ROTATE,VARIABLE}; enum{EQUAL,ATOM}; @@ -216,10 +218,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) : // set omega_rotate from period - if (mstyle == WIGGLE || mstyle == ROTATE) { - double PI = 4.0 * atan(1.0); - omega_rotate = 2.0*PI / period; - } + if (mstyle == WIGGLE || mstyle == ROTATE) omega_rotate = 2.0*MY_PI / period; // runit = unit vector along rotation axis diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp index d0269acddb..109373add7 100644 --- a/src/fix_orient_fcc.cpp +++ b/src/fix_orient_fcc.cpp @@ -28,10 +28,12 @@ #include "neigh_request.h" #include "comm.h" #include "output.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define BIG 1000000000 @@ -77,7 +79,6 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) : // initializations - PI = 4.0*atan(1.0); half_fcc_nn = 6; use_xismooth = false; double xicutoff = 1.57; @@ -344,10 +345,10 @@ void FixOrientFCC::post_force(int vflag) edelta = Vxi; order[i][1] = 1.0; } else { - omega = (0.5*PI)*(xi_total-xi0) / (xi1-xi0); - nbr[i].duxi = PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0)); + omega = MY_PI2*(xi_total-xi0) / (xi1-xi0); + nbr[i].duxi = MY_PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0)); edelta = Vxi*(1 - cos(2.0*omega)) / 2.0; - order[i][1] = omega / (0.5*PI); + order[i][1] = omega / MY_PI2; } added_energy += edelta; } diff --git a/src/fix_orient_fcc.h b/src/fix_orient_fcc.h index f401d30855..b83753619b 100644 --- a/src/fix_orient_fcc.h +++ b/src/fix_orient_fcc.h @@ -58,7 +58,6 @@ class FixOrientFCC : public Fix { private: int me; - double PI; int nlevels_respa; int direction_of_motion; // 1 = center shrinks, 0 = center grows diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp index 43f7f61087..f3048cc18d 100644 --- a/src/fix_restrain.cpp +++ b/src/fix_restrain.cpp @@ -26,10 +26,12 @@ #include "comm.h" #include "respa.h" #include "input.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; enum{DIHEDRAL}; @@ -83,13 +85,12 @@ FixRestrain::FixRestrain(LAMMPS *lmp, int narg, char **arg) : // special treatment for dihedral restraints if (rstyle == DIHEDRAL) { - double PI = 4.0*atan(1.0); cos_shift = (double *) memory->smalloc(n_bonds * sizeof(double), "restrain:cos_shift"); sin_shift = (double *) memory->smalloc(n_bonds * sizeof(double), "restrain:sin_shift"); for (ibond = 0; ibond < n_bonds; ibond++) { - double my_arg = PI * (180.0 + target[ibond]) / 180.0; + double my_arg = MY_PI * (180.0 + target[ibond]) / 180.0; cos_shift[ibond] = cos(my_arg); sin_shift[ibond] = sin(my_arg); } diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp index cf63dfa116..63df87b782 100644 --- a/src/fix_rigid.cpp +++ b/src/fix_rigid.cpp @@ -19,6 +19,8 @@ #include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "domain.h" #include "update.h" #include "respa.h" @@ -28,14 +30,20 @@ #include "random_mars.h" #include "force.h" #include "output.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define TOLERANCE 1.0e-6 #define EPSILON 1.0e-7 +#define SINERTIA 0.4 // moment of inertia prefactor for sphere +#define EINERTIA 0.4 // moment of inertia prefactor for ellipsoid +#define LINERTIA (1.0/12.0) // moment of inertia prefactor for line segment + /* ---------------------------------------------------------------------- */ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : @@ -56,12 +64,12 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // perform initial allocation of atom-based arrays // register with Atom class - extended = dorientflag = qorientflag = 0; + extended = orientflag = dorientflag = 0; body = NULL; displace = NULL; eflags = NULL; + orient = NULL; dorient = NULL; - qorient = NULL; grow_arrays(atom->nmax); atom->add_callback(0); @@ -278,7 +286,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : else error->all(FLERR,"Illegal fix rigid command"); if (domain->dimension == 2 && (xflag == 1.0 || yflag == 1.0)) - error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation"); + error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation"); int count = 0; for (int m = mlo; m <= mhi; m++) { @@ -384,18 +392,24 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) : // bitmasks for properties of extended particles - INERTIA_POINT = 1; - INERTIA_SPHERE = 2; - INERTIA_ELLIPSOID = 4; - ORIENT_DIPOLE = 8; - ORIENT_QUAT = 16; - OMEGA = 32; - ANGMOM = 64; - TORQUE = 128; + POINT = 1; + SPHERE = 2; + ELLIPSOID = 4; + LINE = 8; + TRIANGLE = 16; + DIPOLE = 32; + OMEGA = 64; + ANGMOM = 128; + TORQUE = 256; + + MINUSPI = -MY_PI; + TWOPI = 2.0*MY_PI; // atom style pointers to particles that store extra info avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + avec_line = (AtomVecLine *) atom->style_match("line"); + avec_tri = (AtomVecTri *) atom->style_match("tri"); // print statistics @@ -423,8 +437,8 @@ FixRigid::~FixRigid() memory->destroy(body); memory->destroy(displace); memory->destroy(eflags); + memory->destroy(orient); memory->destroy(dorient); - memory->destroy(qorient); // delete nbody-length arrays @@ -469,7 +483,7 @@ int FixRigid::setmask() void FixRigid::init() { - int i,ibody; + int i,itype,ibody; triclinic = domain->triclinic; @@ -504,24 +518,33 @@ void FixRigid::init() // extended = 1 if any particle in a rigid body is finite size // or has a dipole moment - extended = dorientflag = qorientflag = 0; + extended = orientflag = dorientflag = 0; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **mu = atom->mu; double *radius = atom->radius; double *rmass = atom->rmass; double *mass = atom->mass; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; int *type = atom->type; int nlocal = atom->nlocal; - if (atom->radius_flag || atom->ellipsoid_flag || atom->mu_flag) { + if (atom->radius_flag || atom->ellipsoid_flag || atom->line_flag || + atom->tri_flag || atom->mu_flag) { int flag = 0; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; if (radius && radius[i] > 0.0) flag = 1; if (ellipsoid && ellipsoid[i] >= 0) flag = 1; + if (line && line[i] >= 0) flag = 1; + if (tri && tri[i] >= 0) flag = 1; if (mu && mu[i][3] > 0.0) flag = 1; } @@ -529,35 +552,45 @@ void FixRigid::init() } // grow extended arrays and set extended flags for each particle - // qorientflag = 1 if any particle stores quat orientation + // orientflag = 4 if any particle stores ellipsoid or tri orientation + // orientflag = 1 if any particle stores line orientation // dorientflag = 1 if any particle stores dipole orientation if (extended) { + if (atom->ellipsoid_flag) orientflag = 4; + if (atom->line_flag) orientflag = 1; + if (atom->tri_flag) orientflag = 4; if (atom->mu_flag) dorientflag = 1; - if (atom->ellipsoid_flag) qorientflag = 1; grow_arrays(atom->nmax); for (i = 0; i < nlocal; i++) { eflags[i] = 0; if (body[i] < 0) continue; - // set INERTIA to POINT or SPHERE or ELLIPSOID + // set to POINT or SPHERE or ELLIPSOID or LINE if (radius && radius[i] > 0.0) { - eflags[i] |= INERTIA_SPHERE; + eflags[i] |= SPHERE; eflags[i] |= OMEGA; eflags[i] |= TORQUE; } else if (ellipsoid && ellipsoid[i] >= 0) { - eflags[i] |= INERTIA_ELLIPSOID; - eflags[i] |= ORIENT_QUAT; + eflags[i] |= ELLIPSOID; eflags[i] |= ANGMOM; eflags[i] |= TORQUE; - } else eflags[i] |= INERTIA_POINT; + } else if (line && line[i] >= 0) { + eflags[i] |= LINE; + eflags[i] |= OMEGA; + eflags[i] |= TORQUE; + } else if (tri && tri[i] >= 0) { + eflags[i] |= TRIANGLE; + eflags[i] |= ANGMOM; + eflags[i] |= TORQUE; + } else eflags[i] |= POINT; // set DIPOLE if atom->mu and mu[3] > 0.0 if (atom->mu_flag && mu[i][3] > 0.0) - eflags[i] |= ORIENT_DIPOLE; + eflags[i] |= DIPOLE; } } @@ -592,8 +625,8 @@ void FixRigid::init() if ((xbox && !periodicity[0]) || (ybox && !periodicity[1]) || (zbox && !periodicity[2])) - error->one(FLERR,"Fix rigid atom has non-zero image flag " - "in a non-periodic dimension"); + error->one(FLERR,"Fix rigid atom has non-zero image flag " + "in a non-periodic dimension"); if (triclinic == 0) { xunwrap = x[i][0] + xbox*xprd; @@ -629,7 +662,7 @@ void FixRigid::init() // dx,dy,dz = coords relative to center-of-mass // symmetric 3x3 inertia tensor stored in Voigt notation as 6-vector - double dx,dy,dz; + double dx,dy,dz,rad; for (ibody = 0; ibody < nbody; ibody++) for (i = 0; i < 6; i++) sum[ibody][i] = 0.0; @@ -671,18 +704,19 @@ void FixRigid::init() if (extended) { double ivec[6]; - double *shape,*quatatom; + double *shape,*quatatom,*inertiaatom; + double length,theta; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; massone = rmass[i]; - if (eflags[i] & INERTIA_SPHERE) { - sum[ibody][0] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][1] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][2] += 0.4 * massone * radius[i]*radius[i]; - } else if (eflags[i] & INERTIA_ELLIPSOID) { + if (eflags[i] & SPHERE) { + sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i]; + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; quatatom = ebonus[ellipsoid[i]].quat; MathExtra::inertia_ellipsoid(shape,quatatom,massone,ivec); @@ -692,6 +726,26 @@ void FixRigid::init() sum[ibody][3] += ivec[3]; sum[ibody][4] += ivec[4]; sum[ibody][5] += ivec[5]; + } else if (eflags[i] & LINE) { + length = lbonus[line[i]].length; + theta = lbonus[line[i]].theta; + MathExtra::inertia_line(length,theta,massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + quatatom = tbonus[tri[i]].quat; + MathExtra::inertia_triangle(inertiaatom,quatatom,massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; } } } @@ -715,7 +769,8 @@ void FixRigid::init() tensor[0][1] = tensor[1][0] = all[ibody][5]; ierror = MathExtra::jacobi(tensor,inertia[ibody],evectors); - if (ierror) error->all(FLERR,"Insufficient Jacobi rotations for rigid body"); + if (ierror) error->all(FLERR, + "Insufficient Jacobi rotations for rigid body"); ex_space[ibody][0] = evectors[0][0]; ex_space[ibody][1] = evectors[1][0]; @@ -756,6 +811,7 @@ void FixRigid::init() double qc[4],delta[3]; double *quatatom; + double theta_body; for (i = 0; i < nlocal; i++) { if (body[i] < 0) { @@ -786,20 +842,34 @@ void FixRigid::init() ez_space[ibody],delta,displace[i]); if (extended) { - if (eflags[i] & ORIENT_DIPOLE) { + if (eflags[i] & ELLIPSOID) { + quatatom = ebonus[ellipsoid[i]].quat; + MathExtra::qconjugate(quat[ibody],qc); + MathExtra::quatquat(qc,quatatom,orient[i]); + MathExtra::qnormalize(orient[i]); + } else if (eflags[i] & LINE) { + if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]); + else theta_body = -2.0*acos(quat[ibody][0]); + orient[i][0] = lbonus[line[i]].theta - theta_body; + while (orient[i][0] <= MINUSPI) orient[i][0] += TWOPI; + while (orient[i][0] > MY_PI) orient[i][0] -= TWOPI; + if (orientflag == 4) orient[i][1] = orient[i][2] = orient[i][3] = 0.0; + } else if (eflags[i] & TRIANGLE) { + quatatom = tbonus[tri[i]].quat; + MathExtra::qconjugate(quat[ibody],qc); + MathExtra::quatquat(qc,quatatom,orient[i]); + MathExtra::qnormalize(orient[i]); + } else if (orientflag == 4) { + orient[i][0] = orient[i][1] = orient[i][2] = orient[i][3] = 0.0; + } else if (orientflag == 1) + orient[i][0] = 0.0; + + if (eflags[i] & DIPOLE) { MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody], ez_space[ibody],mu[i],dorient[i]); MathExtra::snormalize3(mu[i][3],dorient[i],dorient[i]); } else if (dorientflag) dorient[i][0] = dorient[i][1] = dorient[i][2] = 0.0; - - if (eflags[i] & ORIENT_QUAT) { - quatatom = ebonus[ellipsoid[i]].quat; - MathExtra::qconjugate(quat[ibody],qc); - MathExtra::quatquat(qc,quatatom,qorient[i]); - MathExtra::qnormalize(qorient[i]); - } else if (qorientflag) - qorient[i][0] = qorient[i][1] = qorient[i][2] = qorient[i][3] = 0.0; } } @@ -831,20 +901,39 @@ void FixRigid::init() if (extended) { double ivec[6]; - double *shape; + double *shape,*inertiaatom; + double length; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; massone = rmass[i]; - if (eflags[i] & INERTIA_SPHERE) { - sum[ibody][0] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][1] += 0.4 * massone * radius[i]*radius[i]; - sum[ibody][2] += 0.4 * massone * radius[i]*radius[i]; - } else if (eflags[i] & INERTIA_ELLIPSOID) { + if (eflags[i] & SPHERE) { + sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i]; + sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i]; + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; - MathExtra::inertia_ellipsoid(shape,qorient[i],massone,ivec); + MathExtra::inertia_ellipsoid(shape,orient[i],massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; + } else if (eflags[i] & LINE) { + length = lbonus[line[i]].length; + MathExtra::inertia_line(length,orient[i][0],massone,ivec); + sum[ibody][0] += ivec[0]; + sum[ibody][1] += ivec[1]; + sum[ibody][2] += ivec[2]; + sum[ibody][3] += ivec[3]; + sum[ibody][4] += ivec[4]; + sum[ibody][5] += ivec[5]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + MathExtra::inertia_triangle(inertiaatom,orient[i],massone,ivec); sum[ibody][0] += ivec[0]; sum[ibody][1] += ivec[1]; sum[ibody][2] += ivec[2]; @@ -894,7 +983,8 @@ void FixRigid::init() ndof += fflag[ibody][0] + fflag[ibody][1] + fflag[ibody][2]; ndof += tflag[ibody][0] + tflag[ibody][1] + tflag[ibody][2]; } - tfactor = force->mvv2e / (ndof * force->boltz); + if (ndof > 0.0) tfactor = force->mvv2e / (ndof * force->boltz); + else tfactor = 0.0; } /* ---------------------------------------------------------------------- */ @@ -996,24 +1086,29 @@ void FixRigid::setup(int vflag) // extended particles add their rotation/torque to angmom/torque of body if (extended) { + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; double **omega_one = atom->omega; double **angmom_one = atom->angmom; double **torque_one = atom->torque; double *radius = atom->radius; + int *line = atom->line; for (i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; if (eflags[i] & OMEGA) { - if (rmass) massone = rmass[i]; - else massone = mass[type[i]]; - radone = radius[i]; - sum[ibody][0] += 0.4 * massone * radone*radone * omega_one[i][0]; - sum[ibody][1] += 0.4 * massone * radone*radone * omega_one[i][1]; - sum[ibody][2] += 0.4 * massone * radone*radone * omega_one[i][2]; + if (eflags[i] & SPHERE) { + radone = radius[i]; + sum[ibody][0] += SINERTIA*rmass[i] * radone*radone * omega_one[i][0]; + sum[ibody][1] += SINERTIA*rmass[i] * radone*radone * omega_one[i][1]; + sum[ibody][2] += SINERTIA*rmass[i] * radone*radone * omega_one[i][2]; + } else if (eflags[i] & LINE) { + radone = lbonus[line[i]].length; + sum[ibody][2] += LINERTIA*rmass[i] * radone*radone * omega_one[i][2]; + } } - if (eflags[i] & ANGMOM) { sum[ibody][0] += angmom_one[i][0]; sum[ibody][1] += angmom_one[i][1]; @@ -1516,7 +1611,7 @@ void FixRigid::deform(int flag) void FixRigid::set_xv() { - int ibody; + int ibody,itype; int xbox,ybox,zbox; double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone; double xy,xz,yz; @@ -1622,43 +1717,64 @@ void FixRigid::set_xv() // set orientation, omega, angmom of each extended particle if (extended) { - double *shape,*quatatom; + double theta_body,theta; + double *shape,*quatatom,*inertiaatom; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecLine::Bonus *lbonus; + if (avec_line) lbonus = avec_line->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **omega_one = atom->omega; double **angmom_one = atom->angmom; double **mu = atom->mu; int *ellipsoid = atom->ellipsoid; + int *line = atom->line; + int *tri = atom->tri; for (int i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; - - if (eflags[i] & ORIENT_DIPOLE) { - MathExtra::quat_to_mat(quat[ibody],p); - MathExtra::matvec(p,dorient[i],mu[i]); - MathExtra::snormalize3(mu[i][3],mu[i],mu[i]); - } - if (eflags[i] & ORIENT_QUAT) { - quatatom = ebonus[ellipsoid[i]].quat; - MathExtra::quatquat(quat[ibody],qorient[i],quatatom); - MathExtra::qnormalize(quatatom); - } - if (eflags[i] & OMEGA) { + + if (eflags[i] & SPHERE) { omega_one[i][0] = omega[ibody][0]; omega_one[i][1] = omega[ibody][1]; omega_one[i][2] = omega[ibody][2]; - } - if (eflags[i] & ANGMOM) { + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; quatatom = ebonus[ellipsoid[i]].quat; - ione[0] = 0.2*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); - ione[1] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); - ione[2] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); + MathExtra::quatquat(quat[ibody],orient[i],quatatom); + MathExtra::qnormalize(quatatom); + ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); + ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); + ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione, angmom_one[i]); + } else if (eflags[i] & LINE) { + if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]); + else theta_body = -2.0*acos(quat[ibody][0]); + theta = orient[i][0] + theta_body; + while (theta <= MINUSPI) theta += TWOPI; + while (theta > MY_PI) theta -= TWOPI; + lbonus[line[i]].theta = theta; + omega_one[i][0] = omega[ibody][0]; + omega_one[i][1] = omega[ibody][1]; + omega_one[i][2] = omega[ibody][2]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + quatatom = tbonus[tri[i]].quat; + MathExtra::quatquat(quat[ibody],orient[i],quatatom); + MathExtra::qnormalize(quatatom); + MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); + MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone, + inertiaatom,angmom_one[i]); + } + if (eflags[i] & DIPOLE) { + MathExtra::quat_to_mat(quat[ibody],p); + MathExtra::matvec(p,dorient[i],mu[i]); + MathExtra::snormalize3(mu[i][3],mu[i],mu[i]); } } } @@ -1672,8 +1788,9 @@ void FixRigid::set_xv() void FixRigid::set_v() { - int ibody; + int ibody,itype; int xbox,ybox,zbox; + double dx,dy,dz; double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone; double xy,xz,yz; double ione[3],exone[3],eyone[3],ezone[3],delta[3],vr[6]; @@ -1761,32 +1878,44 @@ void FixRigid::set_v() // set omega, angmom of each extended particle if (extended) { - double *shape,*quatatom; + double *shape,*quatatom,*inertiaatom; AtomVecEllipsoid::Bonus *ebonus; if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus; + AtomVecTri::Bonus *tbonus; + if (avec_tri) tbonus = avec_tri->bonus; double **omega_one = atom->omega; double **angmom_one = atom->angmom; int *ellipsoid = atom->ellipsoid; + int *tri = atom->tri; for (int i = 0; i < nlocal; i++) { if (body[i] < 0) continue; ibody = body[i]; - if (eflags[i] & OMEGA) { + if (eflags[i] & SPHERE) { omega_one[i][0] = omega[ibody][0]; omega_one[i][1] = omega[ibody][1]; omega_one[i][2] = omega[ibody][2]; - } - if (eflags[i] & ANGMOM) { + } else if (eflags[i] & ELLIPSOID) { shape = ebonus[ellipsoid[i]].shape; quatatom = ebonus[ellipsoid[i]].quat; - ione[0] = 0.2*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); - ione[1] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); - ione[2] = 0.2*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); + ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]); + ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]); + ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]); MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione, angmom_one[i]); + } else if (eflags[i] & LINE) { + omega_one[i][0] = omega[ibody][0]; + omega_one[i][1] = omega[ibody][1]; + omega_one[i][2] = omega[ibody][2]; + } else if (eflags[i] & TRIANGLE) { + inertiaatom = tbonus[tri[i]].inertia; + quatatom = tbonus[tri[i]].quat; + MathExtra::q_to_exyz(quatatom,exone,eyone,ezone); + MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone, + inertiaatom,angmom_one[i]); } } } @@ -1804,8 +1933,8 @@ double FixRigid::memory_usage() bytes += maxvatom*6 * sizeof(double); if (extended) { bytes += nmax * sizeof(int); + if (orientflag) bytes = nmax*orientflag * sizeof(double); if (dorientflag) bytes = nmax*3 * sizeof(double); - if (qorientflag) bytes = nmax*4 * sizeof(double); } return bytes; } @@ -1820,8 +1949,8 @@ void FixRigid::grow_arrays(int nmax) memory->grow(displace,nmax,3,"rigid:displace"); if (extended) { memory->grow(eflags,nmax,"rigid:eflags"); + if (orientflag) memory->grow(orient,nmax,orientflag,"rigid:orient"); if (dorientflag) memory->grow(dorient,nmax,3,"rigid:dorient"); - if (qorientflag) memory->grow(qorient,nmax,4,"rigid:qorient"); } } @@ -1837,17 +1966,13 @@ void FixRigid::copy_arrays(int i, int j) displace[j][2] = displace[i][2]; if (extended) { eflags[j] = eflags[i]; + for (int k = 0; k < orientflag; k++) + orient[j][k] = orient[i][k]; if (dorientflag) { dorient[j][0] = dorient[i][0]; dorient[j][1] = dorient[i][1]; dorient[j][2] = dorient[i][2]; } - if (qorientflag) { - qorient[j][0] = qorient[i][0]; - qorient[j][1] = qorient[i][1]; - qorient[j][2] = qorient[i][2]; - qorient[j][3] = qorient[i][3]; - } } } @@ -1877,17 +2002,13 @@ int FixRigid::pack_exchange(int i, double *buf) int m = 4; buf[m++] = eflags[i]; + for (int j = 0; j < orientflag; j++) + buf[m++] = orient[i][j]; if (dorientflag) { buf[m++] = dorient[i][0]; buf[m++] = dorient[i][1]; buf[m++] = dorient[i][2]; } - if (qorientflag) { - buf[m++] = qorient[i][0]; - buf[m++] = qorient[i][1]; - buf[m++] = qorient[i][2]; - buf[m++] = qorient[i][3]; - } return m; } @@ -1905,17 +2026,13 @@ int FixRigid::unpack_exchange(int nlocal, double *buf) int m = 4; eflags[nlocal] = static_cast (buf[m++]); + for (int j = 0; j < orientflag; j++) + orient[nlocal][j] = buf[m++]; if (dorientflag) { dorient[nlocal][0] = buf[m++]; dorient[nlocal][1] = buf[m++]; dorient[nlocal][2] = buf[m++]; } - if (qorientflag) { - qorient[nlocal][0] = buf[m++]; - qorient[nlocal][1] = buf[m++]; - qorient[nlocal][2] = buf[m++]; - qorient[nlocal][3] = buf[m++]; - } return m; } diff --git a/src/fix_rigid.h b/src/fix_rigid.h index 06121ad47a..fa803df5f7 100644 --- a/src/fix_rigid.h +++ b/src/fix_rigid.h @@ -56,6 +56,7 @@ class FixRigid : public Fix { double dtv,dtf,dtq; double *step_respa; int triclinic; + double MINUSPI,TWOPI; int nbody; // # of rigid bodies int *nrigid; // # of atoms in each rigid body @@ -82,11 +83,11 @@ class FixRigid : public Fix { int **remapflag; // PBC remap flags for each rigid body int extended; // 1 if any particles have extended attributes + int orientflag; // 1 if particles store spatial orientation int dorientflag; // 1 if particles store dipole orientation - int qorientflag; // 1 if particles store quat orientation int *eflags; // flags for extended particles - double **qorient; // rotation state of ext particle wrt rigid body + double **orient; // orientation vector of particle wrt rigid body double **dorient; // orientation of dipole mu wrt rigid body double tfactor; // scale factor on temperature of rigid bodies @@ -104,10 +105,10 @@ class FixRigid : public Fix { class RanMars *random; class AtomVecEllipsoid *avec_ellipsoid; + class AtomVecLine *avec_line; + class AtomVecTri *avec_tri; - // bitmasks for eflags - int INERTIA_POINT,INERTIA_SPHERE,INERTIA_ELLIPSOID; - int ORIENT_DIPOLE,ORIENT_QUAT; + int POINT,SPHERE,ELLIPSOID,LINE,TRIANGLE,DIPOLE; // bitmasks for eflags int OMEGA,ANGMOM,TORQUE; void no_squish_rotate(int, double *, double *, double *, double); diff --git a/src/fix_shake.cpp b/src/fix_shake.cpp index e00e84e424..5cdce3ad25 100644 --- a/src/fix_shake.cpp +++ b/src/fix_shake.cpp @@ -30,10 +30,12 @@ #include "comm.h" #include "group.h" #include "fix_respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; #define BIG 1.0e20 #define MASSDELTA 0.1 @@ -46,8 +48,6 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); - PI = 4.0*atan(1.0); - virial_flag = 1; create_attribute = 1; @@ -2114,7 +2114,7 @@ void FixShake::stats() r3 = sqrt(delx*delx + dely*dely + delz*delz); angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2)); - angle *= 180.0/PI; + angle *= 180.0/MY_PI; m = shake_type[i][2]; a_count[m]++; a_ave[m] += angle; diff --git a/src/fix_shake.h b/src/fix_shake.h index eaf39837cb..b0aa5c63d2 100644 --- a/src/fix_shake.h +++ b/src/fix_shake.h @@ -49,7 +49,6 @@ class FixShake : public Fix { private: int me,nprocs; - double PI; double tolerance; // SHAKE tolerance int max_iter; // max # of SHAKE iterations int output_every; // SHAKE stat output every so often diff --git a/src/improper.cpp b/src/improper.cpp index 0fd566a0a6..9a1f47e5ce 100644 --- a/src/improper.cpp +++ b/src/improper.cpp @@ -28,7 +28,6 @@ Improper::Improper(LAMMPS *lmp) : Pointers(lmp) energy = 0.0; allocated = 0; - PI = 4.0*atan(1.0); maxeatom = maxvatom = 0; eatom = NULL; diff --git a/src/improper.h b/src/improper.h index 1b2413fe61..d766015e34 100644 --- a/src/improper.h +++ b/src/improper.h @@ -39,8 +39,6 @@ class Improper : protected Pointers { virtual double memory_usage(); protected: - double PI; - int evflag; int eflag_either,eflag_global,eflag_atom; int vflag_either,vflag_global,vflag_atom; diff --git a/src/input.cpp b/src/input.cpp index 6960bb2834..a7827f46ce 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -89,7 +89,7 @@ Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp) int iarg = 0; while (iarg < argc) { if (strcmp(argv[iarg],"-var") == 0 || strcmp(argv[iarg],"-v") == 0) { - int jarg = iarg+2; + int jarg = iarg+3; while (jarg < argc && argv[jarg][0] != '-') jarg++; variable->set(argv[iarg+1],jarg-iarg-2,&argv[iarg+2]); iarg = jarg; diff --git a/src/lammps.cpp b/src/lammps.cpp index 09b6a487de..f316a03ad7 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -81,7 +81,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) if (strcmp(arg[iarg],"-partition") == 0 || strcmp(arg[iarg],"-p") == 0) { universe->existflag = 1; - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); iarg++; while (iarg < narg && arg[iarg][0] != '-') { universe->add_world(arg[iarg]); @@ -89,27 +90,32 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) } } else if (strcmp(arg[iarg],"-in") == 0 || strcmp(arg[iarg],"-i") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); inflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-screen") == 0 || strcmp(arg[iarg],"-sc") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); screenflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-log") == 0 || strcmp(arg[iarg],"-l") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); logflag = iarg + 1; iarg += 2; } else if (strcmp(arg[iarg],"-var") == 0 || strcmp(arg[iarg],"-v") == 0) { - if (iarg+3 > narg) error->universe_all(FLERR,"Invalid command-line argument"); - iarg += 2; + if (iarg+3 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); + iarg += 3; while (iarg < narg && arg[iarg][0] != '-') iarg++; } else if (strcmp(arg[iarg],"-echo") == 0 || strcmp(arg[iarg],"-e") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); iarg += 2; } else if (strcmp(arg[iarg],"-pscreen") == 0 || strcmp(arg[iarg],"-ps") == 0) { @@ -125,14 +131,16 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) iarg += 2; } else if (strcmp(arg[iarg],"-cuda") == 0 || strcmp(arg[iarg],"-c") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); if (strcmp(arg[iarg+1],"on") == 0) cudaflag = 1; else if (strcmp(arg[iarg+1],"off") == 0) cudaflag = 0; else error->universe_all(FLERR,"Invalid command-line argument"); iarg += 2; } else if (strcmp(arg[iarg],"-suffix") == 0 || strcmp(arg[iarg],"-sf") == 0) { - if (iarg+2 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+2 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); delete [] suffix; int n = strlen(arg[iarg+1]) + 1; suffix = new char[n]; @@ -141,7 +149,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) iarg += 2; } else if (strcmp(arg[iarg],"-help") == 0 || strcmp(arg[iarg],"-h") == 0) { - if (iarg+1 > narg) error->universe_all(FLERR,"Invalid command-line argument"); + if (iarg+1 > narg) + error->universe_all(FLERR,"Invalid command-line argument"); helpflag = 1; iarg += 1; } else error->universe_all(FLERR,"Invalid command-line argument"); @@ -334,10 +343,12 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) int mpisize; MPI_Type_size(MPI_LMP_TAGINT,&mpisize); if (mpisize != sizeof(tagint)) - error->all(FLERR,"MPI_LMP_TAGINT and tagint in lmptype.h are not compatible"); + error->all(FLERR, + "MPI_LMP_TAGINT and tagint in lmptype.h are not compatible"); MPI_Type_size(MPI_LMP_BIGINT,&mpisize); if (mpisize != sizeof(bigint)) - error->all(FLERR,"MPI_LMP_BIGINT and bigint in lmptype.h are not compatible"); + error->all(FLERR, + "MPI_LMP_BIGINT and bigint in lmptype.h are not compatible"); #ifdef LAMMPS_SMALLBIG if (sizeof(smallint) != 4 || sizeof(tagint) != 4 || sizeof(bigint) != 8) @@ -352,7 +363,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) error->all(FLERR,"Small, tag, big integers are not sized correctly"); #endif - if (sizeof(tagint) == 8) error->all(FLERR,"64-bit atom IDs are not yet supported"); + if (sizeof(tagint) == 8) + error->all(FLERR,"64-bit atom IDs are not yet supported"); // create CUDA class if USER-CUDA installed, unless explicitly switched off // instantiation creates dummy CUDA class if USER-CUDA is not installed diff --git a/src/pair_born.cpp b/src/pair_born.cpp index 406b95a0cc..271b7b1f7a 100644 --- a/src/pair_born.cpp +++ b/src/pair_born.cpp @@ -24,10 +24,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -269,7 +271,6 @@ double PairBorn::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; @@ -277,11 +278,11 @@ double PairBorn::init_one(int i, int j) double rc2 = rc*rc; double rc3 = rc2*rc; double rc5 = rc3*rc2; - etail_ij = 2.0*PI*all[0]*all[1] * + etail_ij = 2.0*MY_PI*all[0]*all[1] * (a[i][j]*exp((sigma[i][j]-rc)/rho1)*rho1* (rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3) + d[i][j]/(5.0*rc5)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1] * + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1] * (-a[i][j]*exp((sigma[i][j]-rc)/rho1) * (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3 - 8.0*d[i][j]/(5.0*rc5)); diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp index 0490f80eea..1a3464e27e 100644 --- a/src/pair_buck.cpp +++ b/src/pair_buck.cpp @@ -20,10 +20,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -249,17 +251,16 @@ double PairBuck::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; double rc = cut[i][j]; double rc2 = rc*rc; double rc3 = rc2*rc; - etail_ij = 2.0*PI*all[0]*all[1]* + etail_ij = 2.0*MY_PI*all[0]*all[1]* (a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]* + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]* (-a[i][j]*exp(-rc/rho1)* (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3); } diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp index 51c179b889..a2f0784a3d 100644 --- a/src/pair_buck_coul_cut.cpp +++ b/src/pair_buck_coul_cut.cpp @@ -24,10 +24,12 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -304,17 +306,16 @@ double PairBuckCoulCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double rho1 = rho[i][j]; double rho2 = rho1*rho1; double rho3 = rho2*rho1; double rc = cut_lj[i][j]; double rc2 = rc*rc; double rc3 = rc2*rc; - etail_ij = 2.0*PI*all[0]*all[1]* + etail_ij = 2.0*MY_PI*all[0]*all[1]* (a[i][j]*exp(-rc/rho1)*rho1*(rc2 + 2.0*rho1*rc + 2.0*rho2) - c[i][j]/(3.0*rc3)); - ptail_ij = (-1/3.0)*2.0*PI*all[0]*all[1]* + ptail_ij = (-1/3.0)*2.0*MY_PI*all[0]*all[1]* (-a[i][j]*exp(-rc/rho1)* (rc3 + 3.0*rho1*rc2 + 6.0*rho2*rc + 6.0*rho3) + 2.0*c[i][j]/rc3); } diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index e7d2027da6..3a5583ce63 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -195,10 +195,11 @@ void PairHybrid::settings(int narg, char **arg) allocated = 0; // count sub-styles by skipping numeric args - // exception is 1st arg of style "table", which is non-numeric word - // exception is 1st two args of style "lj/coul", which are non-numeric - // exception is 1st two args of style "buck/coul", which are non-numeric + // exception is 1st arg of table style, which is non-numeric word + // exception is 1st two args of lj/coul style, which are non-numeric + // exception is 1st two args of buck/coul, which are non-numeric // exception is 1st arg of reax/c style, which is non-numeric + // execption is 1st 6 args of gran styles, which can have NULLs // need a better way to skip these exceptions nstyles = 0; @@ -208,6 +209,8 @@ void PairHybrid::settings(int narg, char **arg) if (strcmp(arg[i],"lj/coul") == 0) i += 2; if (strcmp(arg[i],"buck/coul") == 0) i += 2; if (strcmp(arg[i],"reax/c") == 0) i++; + if (strstr(arg[i],"gran/hooke")) i += 6; + if (strstr(arg[i],"gran/hertz")) i += 6; i++; while (i < narg && (!isalpha(arg[i][0]) || strcmp(arg[i],"NULL") == 0)) i++; nstyles++; @@ -220,10 +223,11 @@ void PairHybrid::settings(int narg, char **arg) // allocate each sub-style and call its settings() with subset of args // define subset of args for a sub-style by skipping numeric args - // exception is 1st arg of style "table", which is non-numeric - // exception is 1st two args of style "lj/coul", which are non-numeric - // exception is 1st two args of style "buck/coul", which are non-numeric + // exception is 1st arg of table style, which is non-numeric word + // exception is 1st two args of lj/coul style, which are non-numeric + // exception is 1st two args of buck/coul, which are non-numeric // exception is 1st arg of reax/c style, which is non-numeric + // execption is 1st 6 args of gran styles, which can have NULLs // need a better way to skip these exceptions int dummy; @@ -246,6 +250,8 @@ void PairHybrid::settings(int narg, char **arg) if (strcmp(arg[i],"lj/coul") == 0) i += 2; if (strcmp(arg[i],"buck/coul") == 0) i += 2; if (strcmp(arg[i],"reax/c") == 0) i++; + if (strstr(arg[i],"gran/hooke")) i += 6; + if (strstr(arg[i],"gran/hertz")) i += 6; i++; while (i < narg && (!isalpha(arg[i][0]) || strcmp(arg[i],"NULL") == 0)) i++; styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]); diff --git a/src/pair_lj96_cut.cpp b/src/pair_lj96_cut.cpp index 76f808dd03..8eb9a3d9d5 100644 --- a/src/pair_lj96_cut.cpp +++ b/src/pair_lj96_cut.cpp @@ -29,10 +29,12 @@ #include "update.h" #include "integrate.h" #include "respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -589,15 +591,14 @@ double PairLJ96Cut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig3 = sigma[i][j]*sigma[i][j]*sigma[i][j]; double sig6 = sig3*sig3; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig3 - 2.0*rc3) / (6.0*rc6); - ptail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (3.0*sig3 - 4.0*rc3) / (6.0*rc6); } diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp index 671d6420cf..44d86990df 100644 --- a/src/pair_lj_cut.cpp +++ b/src/pair_lj_cut.cpp @@ -29,10 +29,12 @@ #include "update.h" #include "integrate.h" #include "respa.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -583,15 +585,14 @@ double PairLJCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut[i][j]*cut[i][j]*cut[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); } diff --git a/src/pair_lj_cut_coul_cut.cpp b/src/pair_lj_cut_coul_cut.cpp index 1d311d4b72..c6973b2580 100644 --- a/src/pair_lj_cut_coul_cut.cpp +++ b/src/pair_lj_cut_coul_cut.cpp @@ -21,10 +21,12 @@ #include "force.h" #include "neighbor.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -300,15 +302,14 @@ double PairLJCutCoulCut::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double rc3 = cut_lj[i][j]*cut_lj[i][j]*cut_lj[i][j]; double rc6 = rc3*rc3; double rc9 = rc3*rc6; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (sig6 - 3.0*rc6) / (9.0*rc9); - ptail_ij = 16.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9); } diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp index 57110ac81c..10e69ba977 100644 --- a/src/pair_lj_expand.cpp +++ b/src/pair_lj_expand.cpp @@ -19,10 +19,12 @@ #include "comm.h" #include "force.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ @@ -259,7 +261,6 @@ double PairLJExpand::init_one(int i, int j) } MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world); - double PI = 4.0*atan(1.0); double sig2 = sigma[i][j]*sigma[i][j]; double sig6 = sig2*sig2*sig2; double shiftcut = shift[i][j] - cut[i][j]; @@ -273,11 +274,11 @@ double PairLJExpand::init_one(int i, int j) double rc12 = rc11*shiftcut; double shift2 = shift[i][j]*shift[i][j]; double shift3 = shift2*shift[i][j]; - etail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6*((-1.0/(9.0*rc9) + shift[i][j]/(5.0*rc10) - shift2/(11.0*rc11))*sig6 + 1.0/(3.0*rc3) - shift[i][j]/(2.0*rc4) + shift2/(5.0*rc5)); - ptail_ij = 8.0*PI*all[0]*all[1]*epsilon[i][j] * + ptail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] * sig6* ((-4.0/(3.0*rc9) + 18.0*shift[i][j]/(5.0*rc10) - 36.0*shift2/(11.0*rc11) + shift3/rc12)*sig6 + 2.0/rc3 - 9.0*shift[i][j]/(2.0*rc4) + diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp index ce25f4a782..63f0b72b05 100644 --- a/src/pair_soft.cpp +++ b/src/pair_soft.cpp @@ -21,17 +21,16 @@ #include "force.h" #include "update.h" #include "neigh_list.h" +#include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; +using namespace MathConst; /* ---------------------------------------------------------------------- */ -PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp) -{ - PI = 4.0*atan(1.0); -} +PairSoft::PairSoft(LAMMPS *lmp) : Pair(lmp) {} /* ---------------------------------------------------------------------- */ @@ -95,9 +94,9 @@ void PairSoft::compute(int eflag, int vflag) if (rsq < cutsq[itype][jtype]) { r = sqrt(rsq); - arg = PI*r/cut[itype][jtype]; + arg = MY_PI*r/cut[itype][jtype]; if (r > 0.0) fpair = factor_lj * prefactor[itype][jtype] * - sin(arg) * PI/cut[itype][jtype]/r; + sin(arg) * MY_PI/cut[itype][jtype]/r; else fpair = 0.0; f[i][0] += delx*fpair; @@ -290,9 +289,9 @@ double PairSoft::single(int i, int j, int itype, int jtype, double rsq, double r,arg,philj; r = sqrt(rsq); - arg = PI*r/cut[itype][jtype]; + arg = MY_PI*r/cut[itype][jtype]; fforce = factor_lj * prefactor[itype][jtype] * - sin(arg) * PI/cut[itype][jtype]/r; + sin(arg) * MY_PI/cut[itype][jtype]/r; philj = prefactor[itype][jtype] * (1.0+cos(arg)); return factor_lj*philj; diff --git a/src/pair_soft.h b/src/pair_soft.h index 1558f899bc..5cb8950659 100644 --- a/src/pair_soft.h +++ b/src/pair_soft.h @@ -43,7 +43,6 @@ class PairSoft : public Pair { void *extract(char *, int &); protected: - double PI; double cut_global; double **prefactor; double **cut; diff --git a/src/read_data.cpp b/src/read_data.cpp index 3b5d0bc89e..9f9c54f99e 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -21,6 +21,8 @@ #include "atom.h" #include "atom_vec.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "comm.h" #include "update.h" #include "force.h" @@ -42,7 +44,10 @@ using namespace LAMMPS_NS; #define DELTA 4 // must be 2 or larger // customize for new sections -#define NSECTIONS 21 // change when add to header::section_keywords +#define NSECTIONS 23 // change when add to header::section_keywords + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) /* ---------------------------------------------------------------------- */ @@ -60,6 +65,10 @@ ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp) nellipsoids = 0; avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + nlines = 0; + avec_line = (AtomVecLine *) atom->style_match("line"); + ntris = 0; + avec_tri = (AtomVecTri *) atom->style_match("tri"); } /* ---------------------------------------------------------------------- */ @@ -150,8 +159,18 @@ void ReadData::command(int narg, char **arg) } else if (strcmp(keyword,"Ellipsoids") == 0) { if (!avec_ellipsoid) error->one(FLERR,"Invalid data file section: Ellipsoids"); - if (atomflag == 0) error->one(FLERR,"Must read Atoms before Ellipsoids"); - ellipsoids(); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids"); + bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids"); + } else if (strcmp(keyword,"Lines") == 0) { + if (!avec_line) + error->one(FLERR,"Invalid data file section: Lines"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines"); + bonus(nlines,(AtomVec *) avec_line,"lines"); + } else if (strcmp(keyword,"Triangles") == 0) { + if (!avec_tri) + error->one(FLERR,"Invalid data file section: Triangles"); + if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles"); + bonus(ntris,(AtomVec *) avec_tri,"triangles"); } else if (strcmp(keyword,"Bonds") == 0) { if (atom->avec->bonds_allow == 0) @@ -222,25 +241,31 @@ void ReadData::command(int narg, char **arg) if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before " + "MiddleBondTorsion Coeffs"); dihedralcoeffs(1); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before EndBondTorsion Coeffs"); dihedralcoeffs(2); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before AngleTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before AngleTorsion Coeffs"); dihedralcoeffs(3); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before " + "AngleAngleTorsion Coeffs"); dihedralcoeffs(4); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) @@ -274,7 +299,8 @@ void ReadData::command(int narg, char **arg) // error if natoms > 0 yet no atoms were read - if (atom->natoms > 0 && atomflag == 0) error->one(FLERR,"No atoms in data file"); + if (atom->natoms > 0 && atomflag == 0) + error->one(FLERR,"No atoms in data file"); // create bond topology now that system is defined @@ -303,7 +329,7 @@ void ReadData::header(int flag) // customize for new sections char *section_keywords[NSECTIONS] = - {"Atoms","Velocities","Ellipsoids", + {"Atoms","Velocities","Ellipsoids","Lines","Triangles", "Bonds","Angles","Dihedrals","Impropers", "Masses","Pair Coeffs","Bond Coeffs","Angle Coeffs", "Dihedral Coeffs","Improper Coeffs", @@ -373,6 +399,14 @@ void ReadData::header(int flag) if (!avec_ellipsoid) error->one(FLERR,"No ellipsoids allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nellipsoids); + } else if (strstr(line,"lines")) { + if (!avec_line) + error->one(FLERR,"No lines allowed with this atom style"); + sscanf(line,BIGINT_FORMAT,&nlines); + } else if (strstr(line,"triangles")) { + if (!avec_tri) + error->one(FLERR,"No triangles allowed with this atom style"); + sscanf(line,BIGINT_FORMAT,&ntris); } else if (strstr(line,"xlo xhi")) @@ -475,7 +509,8 @@ void ReadData::atoms() if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms); } - if (natoms != atom->natoms) error->all(FLERR,"Did not assign all atoms correctly"); + if (natoms != atom->natoms) + error->all(FLERR,"Did not assign all atoms correctly"); // if any atom ID < 0, error // if all atom IDs = 0, tag_enable = 0 @@ -568,11 +603,11 @@ void ReadData::velocities() } /* ---------------------------------------------------------------------- - read all ellipsoids + read all bonus data to find atoms, must build atom map if not a molecular system ------------------------------------------------------------------------- */ -void ReadData::ellipsoids() +void ReadData::bonus(bigint nbonus, AtomVec *ptr, char *type) { int i,m,nchunk; @@ -585,7 +620,7 @@ void ReadData::ellipsoids() } bigint nread = 0; - bigint natoms = nellipsoids; + bigint natoms = nbonus; while (nread < natoms) { if (natoms-nread > CHUNK) nchunk = CHUNK; @@ -603,7 +638,7 @@ void ReadData::ellipsoids() MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); - atom->data_bonus(nchunk,buffer,avec_ellipsoid); + atom->data_bonus(nchunk,buffer,ptr); nread += nchunk; } @@ -613,8 +648,8 @@ void ReadData::ellipsoids() } if (me == 0) { - if (screen) fprintf(screen," " BIGINT_FORMAT " ellipsoids\n",natoms); - if (logfile) fprintf(logfile," " BIGINT_FORMAT " ellipsoids\n",natoms); + if (screen) fprintf(screen," " BIGINT_FORMAT " %s\n",natoms,type); + if (logfile) fprintf(logfile," " BIGINT_FORMAT " %s\n",natoms,type); } } @@ -660,7 +695,8 @@ void ReadData::bonds() if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor); } - if (sum != factor*atom->nbonds) error->all(FLERR,"Bonds assigned incorrectly"); + if (sum != factor*atom->nbonds) + error->all(FLERR,"Bonds assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -705,7 +741,8 @@ void ReadData::angles() if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor); } - if (sum != factor*atom->nangles) error->all(FLERR,"Angles assigned incorrectly"); + if (sum != factor*atom->nangles) + error->all(FLERR,"Angles assigned incorrectly"); } /* ---------------------------------------------------------------------- */ @@ -1010,6 +1047,8 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, int natoms = static_cast (atom->natoms); bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0; int ellipsoid_flag = 0; + int line_flag = 0; + int tri_flag = 0; // customize for new sections // allocate topology counting vector @@ -1031,6 +1070,14 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, error->one(FLERR,"Invalid data file section: Ellipsoids"); ellipsoid_flag = 1; skip_lines(nellipsoids); + } else if (strcmp(keyword,"Lines") == 0) { + if (!avec_line) error->one(FLERR,"Invalid data file section: Lines"); + line_flag = 1; + skip_lines(nlines); + } else if (strcmp(keyword,"Triangles") == 0) { + if (!avec_tri) error->one(FLERR,"Invalid data file section: Triangles"); + tri_flag = 1; + skip_lines(ntris); } else if (strcmp(keyword,"Pair Coeffs") == 0) { if (force->pair == NULL) @@ -1077,25 +1124,31 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before " + "MiddleBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before EndBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before AngleTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before AngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->one(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) - error->one(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs"); + error->one(FLERR, + "Must define dihedral_style before " + "AngleAngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) @@ -1252,6 +1305,10 @@ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, if (nellipsoids && !ellipsoid_flag) error->one(FLERR,"Needed bonus data not in data file"); + if (nlines && !line_flag) + error->one(FLERR,"Needed bonus data not in data file"); + if (ntris && !tri_flag) + error->one(FLERR,"Needed bonus data not in data file"); } /* ---------------------------------------------------------------------- diff --git a/src/read_data.h b/src/read_data.h index 80fd441413..67398469c5 100644 --- a/src/read_data.h +++ b/src/read_data.h @@ -40,6 +40,10 @@ class ReadData : protected Pointers { bigint nellipsoids; class AtomVecEllipsoid *avec_ellipsoid; + bigint nlines; + class AtomVecLine *avec_line; + bigint ntris; + class AtomVecTri *avec_tri; void open(char *); void scan(int &, int &, int &, int &); @@ -51,7 +55,7 @@ class ReadData : protected Pointers { void atoms(); void velocities(); - void ellipsoids(); + void bonus(bigint, class AtomVec *, char *); void bonds(); void angles(); diff --git a/src/set.cpp b/src/set.cpp index 507fa812f5..2a4c25731b 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -19,6 +19,8 @@ #include "atom.h" #include "atom_vec.h" #include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" #include "domain.h" #include "region.h" #include "group.h" @@ -28,16 +30,15 @@ #include "pair.h" #include "random_park.h" #include "math_extra.h" -#include "error.h" - #include "math_const.h" +#include "error.h" 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, - DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM, +enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,LENGTH,TRI, + DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,THETA,ANGMOM, DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER, MESO_E,MESO_CV,MESO_RHO}; @@ -95,7 +96,8 @@ void Set::command(int narg, char **arg) error->all(FLERR,"Invalid value in set command"); if (fraction < 0.0 || fraction > 1.0) error->all(FLERR,"Invalid value in set command"); - if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); + if (ivalue <= 0) + error->all(FLERR,"Invalid random number seed in set command"); setrandom(TYPE_FRACTION); iarg += 4; } else if (strcmp(arg[iarg],"mol") == 0) { @@ -150,6 +152,22 @@ void Set::command(int narg, char **arg) } set(SHAPE); iarg += 4; + } else if (strcmp(arg[iarg],"length") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + dvalue = atof(arg[iarg+1]); + if (!atom->line_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command"); + set(LENGTH); + iarg += 2; + } else if (strcmp(arg[iarg],"tri") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + dvalue = atof(arg[iarg+1]); + if (!atom->tri_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command"); + set(TRI); + iarg += 2; } else if (strcmp(arg[iarg],"dipole") == 0) { if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); xvalue = atof(arg[iarg+1]); @@ -165,8 +183,10 @@ void Set::command(int narg, char **arg) dvalue = atof(arg[iarg+2]); if (!atom->mu_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); - if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); - if (dvalue <= 0.0) error->all(FLERR,"Invalid dipole length in set command"); + if (ivalue <= 0) + error->all(FLERR,"Invalid random number seed in set command"); + if (dvalue <= 0.0) + error->all(FLERR,"Invalid dipole length in set command"); setrandom(DIPOLE_RANDOM); iarg += 3; } else if (strcmp(arg[iarg],"quat") == 0) { @@ -175,18 +195,36 @@ void Set::command(int narg, char **arg) yvalue = atof(arg[iarg+2]); zvalue = atof(arg[iarg+3]); wvalue = atof(arg[iarg+4]); - if (!atom->ellipsoid_flag) + if (!atom->ellipsoid_flag && !atom->tri_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); set(QUAT); iarg += 5; } else if (strcmp(arg[iarg],"quat/random") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); ivalue = atoi(arg[iarg+1]); - if (!atom->ellipsoid_flag) + if (!atom->ellipsoid_flag && !atom->tri_flag) error->all(FLERR,"Cannot set this attribute for this atom style"); - if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); + if (ivalue <= 0) + error->all(FLERR,"Invalid random number seed in set command"); setrandom(QUAT_RANDOM); iarg += 2; + } else if (strcmp(arg[iarg],"theta") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + dvalue = atof(arg[iarg+1]); + dvalue *= MY_PI/180.0; + if (!atom->line_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + set(THETA); + iarg += 2; + } else if (strcmp(arg[iarg],"angmom") == 0) { + if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + xvalue = atof(arg[iarg+1]); + yvalue = atof(arg[iarg+2]); + zvalue = atof(arg[iarg+3]); + if (!atom->ellipsoid_flag && !atom->tri_flag) + error->all(FLERR,"Cannot set this attribute for this atom style"); + set(ANGMOM); + iarg += 4; } else if (strcmp(arg[iarg],"diameter") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); dvalue = atof(arg[iarg+1]); @@ -225,11 +263,14 @@ void Set::command(int narg, char **arg) zimage = atoi(arg[iarg+3]); } if (ximageflag && ximage && !domain->xperiodic) - error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR, + "Cannot set non-zero image flag for non-periodic dimension"); if (yimageflag && yimage && !domain->yperiodic) - error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR, + "Cannot set non-zero image flag for non-periodic dimension"); if (zimageflag && zimage && !domain->zperiodic) - error->all(FLERR,"Cannot set non-zero image flag for non-periodic dimension"); + error->all(FLERR, + "Cannot set non-zero image flag for non-periodic dimension"); set(IMAGE); iarg += 4; } else if (strcmp(arg[iarg],"bond") == 0) { @@ -379,6 +420,8 @@ void Set::set(int keyword) { AtomVecEllipsoid *avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line"); + AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri"); selection(atom->nlocal); @@ -399,23 +442,49 @@ void Set::set(int keyword) else if (keyword == MESO_CV) atom->cv[i] = dvalue; else if (keyword == MESO_RHO) atom->rho[i] = dvalue; - // set shape + // set shape of ellipsoidal particle else if (keyword == SHAPE) avec_ellipsoid->set_shape(i,0.5*xvalue,0.5*yvalue,0.5*zvalue); + // set length of line particle + + else if (keyword == LENGTH) + avec_line->set_length(i,dvalue); + + // set corners of tri particle + + else if (keyword == TRI) + avec_tri->set_equilateral(i,dvalue); + // set rmass via density // if radius > 0.0, treat as sphere // if shape > 0.0, treat as ellipsoid + // if length > 0.0, treat as line + // if area > 0.0, treat as tri // else set rmass to density directly else if (keyword == DENSITY) { if (atom->radius_flag && atom->radius[i] > 0.0) - atom->rmass[i] = 4.0*MY_PI*THIRD * + atom->rmass[i] = 4.0*MY_PI/3.0 * atom->radius[i]*atom->radius[i]*atom->radius[i] * dvalue; else if (atom->ellipsoid_flag && atom->ellipsoid[i] >= 0) { double *shape = avec_ellipsoid->bonus[atom->ellipsoid[i]].shape; - atom->rmass[i] = 4.0*MY_PI*THIRD * shape[0]*shape[1]*shape[2] * dvalue; + atom->rmass[i] = 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2] * dvalue; + } else if (atom->line_flag && atom->line[i] >= 0) { + double length = avec_line->bonus[atom->line[i]].length; + atom->rmass[i] = length * dvalue; + } else if (atom->tri_flag && atom->tri[i] >= 0) { + double *c1 = avec_tri->bonus[atom->tri[i]].c1; + double *c2 = avec_tri->bonus[atom->tri[i]].c2; + double *c3 = avec_tri->bonus[atom->tri[i]].c3; + double c2mc1[2],c3mc1[3]; + MathExtra::sub3(c2,c1,c2mc1); + MathExtra::sub3(c3,c1,c3mc1); + double norm[3]; + MathExtra::cross3(c2mc1,c3mc1,norm); + double area = 0.5 * MathExtra::len3(norm); + atom->rmass[i] = area * dvalue; } else atom->rmass[i] = dvalue; // reset any or all of 3 image flags @@ -440,12 +509,17 @@ void Set::set(int keyword) mu[i][3] = sqrt(mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]); - // set quaternion orientation + // set quaternion orientation of ellipsoid or tri particle } else if (keyword == QUAT) { - if (atom->ellipsoid[i] < 0) - error->one(FLERR,"Cannot set quaternion for atom that is not an ellipsoid"); - double *quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + double *quat; + if (avec_ellipsoid && atom->ellipsoid[i] >= 0) + quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + else if (avec_tri && atom->tri[i] >= 0) + quat = avec_tri->bonus[atom->tri[i]].quat; + else + error->one(FLERR,"Cannot set quaternion for atom that has none"); + double theta2 = MY_PI2 * wvalue/180.0; double sintheta2 = sin(theta2); quat[0] = cos(theta2); @@ -453,7 +527,22 @@ void Set::set(int keyword) quat[2] = yvalue * sintheta2; quat[3] = zvalue * sintheta2; MathExtra::qnormalize(quat); + + // set theta of line particle + + } else if (keyword == THETA) { + if (atom->line[i] < 0) + error->one(FLERR,"Cannot set theta for atom that is not a line"); + avec_line->bonus[atom->line[i]].theta = dvalue; + + // set angmom of ellipsoidal or tri particle + + } else if (keyword == ANGMOM) { + atom->angmom[i][0] = xvalue; + atom->angmom[i][1] = yvalue; + atom->angmom[i][2] = zvalue; } + count++; } } @@ -468,6 +557,11 @@ void Set::setrandom(int keyword) { int i; + AtomVecEllipsoid *avec_ellipsoid = + (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line"); + AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri"); + selection(atom->nlocal); RanPark *random = new RanPark(lmp,1); double **x = atom->x; @@ -528,13 +622,10 @@ void Set::setrandom(int keyword) } // set quaternions to random orientations in 3d or 2d - // no need to normalize quats since creations algorithms already do } else if (keyword == QUAT_RANDOM) { - AtomVecEllipsoid *avec_ellipsoid = - (AtomVecEllipsoid *) atom->style_match("ellipsoid"); - AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus; int *ellipsoid = atom->ellipsoid; + int *tri = atom->tri; int nlocal = atom->nlocal; double *quat; @@ -542,10 +633,13 @@ void Set::setrandom(int keyword) double s,t1,t2,theta1,theta2; for (i = 0; i < nlocal; i++) if (select[i]) { - if (ellipsoid[i] < 0) - error->one(FLERR,"Cannot set quaternion for atom " - "that is not an ellipsoid"); - quat = bonus[ellipsoid[i]].quat; + if (avec_ellipsoid && atom->ellipsoid[i] >= 0) + quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + else if (avec_tri && atom->tri[i] >= 0) + quat = avec_tri->bonus[atom->tri[i]].quat; + else + error->one(FLERR,"Cannot set quaternion for atom that has none"); + random->reset(seed,x[i]); s = random->uniform(); t1 = sqrt(1.0-s); @@ -563,10 +657,11 @@ void Set::setrandom(int keyword) double theta2; for (i = 0; i < nlocal; i++) if (select[i]) { - if (ellipsoid[i] < 0) - error->one(FLERR,"Cannot set quaternion for atom " - "that is not an ellipsoid"); - quat = bonus[ellipsoid[i]].quat; + if (avec_ellipsoid && atom->ellipsoid[i] >= 0) + quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat; + else + error->one(FLERR,"Cannot set quaternion for atom that has none"); + random->reset(seed,x[i]); theta2 = MY_PI*random->uniform(); quat[0] = cos(theta2); diff --git a/src/set.h b/src/set.h index 5e1fd4e8c7..00e0c77de1 100644 --- a/src/set.h +++ b/src/set.h @@ -35,7 +35,6 @@ class Set : protected Pointers { int style,ivalue,newtype,count; int ximage,yimage,zimage,ximageflag,yimageflag,zimageflag; double dvalue,xvalue,yvalue,zvalue,wvalue,fraction; - double PI; void selection(int); void set(int); diff --git a/src/thermo.cpp b/src/thermo.cpp index a522ea9f7e..495f54c400 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -36,6 +36,7 @@ #include "kspace.h" #include "output.h" #include "timer.h" +#include "math_const.h" #include "memory.h" #include "error.h" diff --git a/src/version.h b/src/version.h index 4d760c21f6..522b480dc6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "6 Oct 2011" +#define LAMMPS_VERSION "20 Oct 2011" diff --git a/tools/amber2lmp/amber2lammps.py b/tools/amber2lmp/amber2lammps.py index c47a17cfe6..08bdf38d9e 100644 --- a/tools/amber2lmp/amber2lammps.py +++ b/tools/amber2lmp/amber2lammps.py @@ -1,993 +1,993 @@ -#! /usr/bin/python - -# -# This is amber2lammps, a program written by Keir E. Novik to convert -# Amber files to Lammps files. -# -# Copyright 1999, 2000 Keir E. Novik; all rights reserved. -# -# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README -# - -#============================================================ - -def Pop(S, I=-1): - 'Pop item I from list' - X = S[I] - del S[I] - return X - -#============================================================ - -class Lammps: - - #-------------------------------------------------------- - - def Dump(self): - 'Write out contents of self (intended for debugging)' - Name_list = self.__dict__.keys() - Name_list.sort() - for Name in Name_list: - print Name + ':', self.__dict__[Name] - - #-------------------------------------------------------- - - def Write_data(self, Basename, Item_list): - 'Write the Lammps data to file (used by Write_Lammps)' - import os, sys - - Filename = 'data.' + Basename - - Dir_list = os.listdir('.') - i = 1 - while Filename in Dir_list: - Filename = 'data' + `i` + '.' + Basename - i = i +1 - del i - - print 'Writing', Filename + '...', - sys.stdout.flush() - - try: - F = open(Filename, 'w') - except IOError, Detail: - print '(error:', Detail[1] + '!)' - return - - try: - F.writelines(Item_list) - except IOError, Detail: - print '(error:', Detail[1] + '!)' - F.close() - return - - F.close() - print 'done.' - - #-------------------------------------------------------- - - def Write_Lammps(self, Basename): - 'Write the Lammps data file, ignoring blank sections' - import string - L = [] - - L.append('LAMMPS data file for ' + self.name + '\n\n') - - L.append(`self.atoms` + ' atoms\n') - L.append(`self.bonds` + ' bonds\n') - L.append(`self.angles` + ' angles\n') - L.append(`self.dihedrals` + ' dihedrals\n') - L.append(`self.impropers` + ' impropers\n\n') - - L.append(`self.atom_types` + ' atom types\n') - if self.bonds > 0: - L.append(`self.bond_types` + ' bond types\n') - if self.angles > 0: - L.append(`self.angle_types` + ' angle types\n') - if self.dihedrals > 0: - L.append(`self.dihedral_types` + ' dihedral types\n') - L.append('\n') - - L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n') - L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n') - L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n') - - if self.atom_types != 0: - L.append('Masses\n\n') - for i in range(self.atom_types): - L.append(`i+1` + ' ' + `self.Masses[i]` + '\n') - L.append('\n') - - L.append('Pair Coeffs\n\n') - for i in range(self.atom_types): - L.append(`i+1`) - for j in range(len(self.Nonbond_Coeffs[0])): - L.append(' ' + `self.Nonbond_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.bonds != 0 and self.bond_types != 0: - L.append('Bond Coeffs\n\n') - for i in range(self.bond_types): - L.append(`i+1`) - for j in range(len(self.Bond_Coeffs[0])): - L.append(' ' + `self.Bond_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.angles != 0 and self.angle_types != 0: - L.append('Angle Coeffs\n\n') - for i in range(self.angle_types): - L.append(`i+1`) - for j in range(len(self.Angle_Coeffs[0])): - L.append(' ' + `self.Angle_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.dihedrals != 0 and self.dihedral_types != 0: - L.append('Dihedral Coeffs\n\n') - for i in range(self.dihedral_types): - L.append(`i+1`) - for j in range(len(self.Dihedral_Coeffs[0])): - L.append(' ' + `self.Dihedral_Coeffs[i][j]`) - L.append('\n') - L.append('\n') - - if self.atoms != 0: - L.append('Atoms\n\n') - for i in range(self.atoms): - L.append(`i+1`) - for j in range(len(self.Atoms[0])): - L.append(' ' + `self.Atoms[i][j]`) - L.append('\n') - L.append('\n') - - if self.bonds != 0 and self.bond_types != 0: - L.append('Bonds\n\n') - for i in range(self.bonds): - L.append(`i+1`) - for j in range(len(self.Bonds[0])): - L.append(' ' + `self.Bonds[i][j]`) - L.append('\n') - L.append('\n') - - if self.angles != 0 and self.angle_types != 0: - L.append('Angles\n\n') - for i in range(self.angles): - L.append(`i+1`) - for j in range(len(self.Angles[0])): - L.append(' ' + `self.Angles[i][j]`) - L.append('\n') - L.append('\n') - - if self.dihedrals != 0 and self.dihedral_types != 0: - L.append('Dihedrals\n\n') - for i in range(self.dihedrals): - L.append(`i+1`) - for j in range(len(self.Dihedrals[0])): - L.append(' ' + `self.Dihedrals[i][j]`) - L.append('\n') - L.append('\n') - - self.Write_data(Basename, L) - -#============================================================ - -class Amber: - def __init__(self): - 'Initialise the Amber class' - self.CRD_is_read = 0 - self.TOP_is_read = 0 - - #-------------------------------------------------------- - - def Dump(self): - 'Write out contents of self (intended for debugging)' - Name_list = self.__dict__.keys() - Name_list.sort() - for Name in Name_list: - print Name + ':', self.__dict__[Name] - - #-------------------------------------------------------- - - def Coerce_to_Lammps(self): - 'Return the Amber data converted to Lammps format' - - import math - - if self.CRD_is_read and self.TOP_is_read: - l = Lammps() - print 'Converting...', - - l.name = self.ITITL - l.atoms = self.NATOM - l.bonds = self.NBONH + self.MBONA - l.angles = self.NTHETH + self.MTHETA - l.dihedrals = self.NPHIH + self.MPHIA - l.impropers = 0 - l.atom_types = self.NTYPES - l.bond_types = self.NUMBND - l.angle_types = self.NUMANG - l.dihedral_types = self.NPTRA - - Shift = 0 - if self.__dict__.has_key('BOX'): - l.xlo = 0.0 - l.xhi = self.BOX[0] - l.ylo = 0.0 - l.yhi = self.BOX[1] - l.zlo = 0.0 - l.zhi = self.BOX[2] - if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \ - (l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \ - (l.zlo > min(self.Z)) or (l.zhi < max(self.Z)): - # Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS - # take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box, - # please uncomment the below 2 lines. - print '(warning: Currently not shifting the atoms to the periodic box)' - #Shift = 1 - else: - print '(warning: Guessing at periodic box!)', - l.xlo = min(self.X) - l.xhi = max(self.X) - l.ylo = min(self.Y) - l.yhi = max(self.Y) - l.zlo = min(self.Z) - l.zhi = max(self.Z) - - # This doesn't check duplicate values - l.Masses = [] - for i in range(l.atom_types): - l.Masses.append(0) - for i in range(self.NATOM): - l.Masses[self.IAC[i] - 1] = self.AMASS[i] - - l.Nonbond_Coeffs = [] - for i in range(self.NTYPES): - l.Nonbond_Coeffs.append([0,0]) - for i in range(self.NTYPES): - j = self.ICO[i * (self.NTYPES + 1)] - 1 - if self.CN1[j] == 0.0: - l.Nonbond_Coeffs[i][0] = 0.0 - else: - l.Nonbond_Coeffs[i][0] = \ - 0.25 * (self.CN2[j])**2 / self.CN1[j] - if self.CN2[j] == 0.0: - l.Nonbond_Coeffs[i][1] = 0.0 - else: - l.Nonbond_Coeffs[i][1] = \ - (self.CN1[j] / self.CN2[j])**(1.0/6.0) - - l.Bond_Coeffs = [] - for i in range(self.NUMBND): - l.Bond_Coeffs.append([0,0]) - for i in range(self.NUMBND): - l.Bond_Coeffs[i][0] = self.RK[i] - l.Bond_Coeffs[i][1] = self.REQ[i] - - l.Angle_Coeffs = [] - for i in range(self.NUMANG): - l.Angle_Coeffs.append([0,0]) - for i in range(self.NUMANG): - l.Angle_Coeffs[i][0] = self.TK[i] - l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i] - - l.Dihedral_Coeffs = [] - for i in range(self.NPTRA): - l.Dihedral_Coeffs.append([0,0,0]) - for i in range(self.NPTRA): - l.Dihedral_Coeffs[i][0] = self.PK[i] - if self.PHASE[i] == 0: - l.Dihedral_Coeffs[i][1] = 1 - else: - l.Dihedral_Coeffs[i][1] = -1 - l.Dihedral_Coeffs[i][2] = int(self.PN[i]) - - l.Atoms = [] - for i in range(self.NATOM): - x = self.X[i] - y = self.Y[i] - z = self.Z[i] - if Shift: - while x < l.xlo: - x = x + self.BOX[0] - while x > l.xhi: - x = x - self.BOX[0] - while y < l.ylo: - y = y + self.BOX[1] - while y > l.yhi: - y = y - self.BOX[1] - while z < l.zlo: - z = z + self.BOX[2] - while z > l.zhi: - z = z - self.BOX[2] - l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \ - x, y, z]) - - l.Bonds = [] - for i in range(l.bonds): - l.Bonds.append([0,0,0]) - for i in range(self.NBONH): - l.Bonds[i][0] = self.ICBH[i] - l.Bonds[i][1] = abs(self.IBH[i])/3 + 1 - l.Bonds[i][2] = abs(self.JBH[i])/3 + 1 - for i in range(self.NBONA): - l.Bonds[self.NBONH + i][0] = self.ICB[i] - l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1 - l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1 - - l.Angles = [] - for i in range(l.angles): - l.Angles.append([0,0,0,0]) - for i in range(self.NTHETH): - l.Angles[i][0] = self.ICTH[i] - l.Angles[i][1] = abs(self.ITH[i])/3 + 1 - l.Angles[i][2] = abs(self.JTH[i])/3 + 1 - l.Angles[i][3] = abs(self.KTH[i])/3 + 1 - for i in range(self.NTHETA): - l.Angles[self.NTHETH + i][0] = self.ICT[i] - l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1 - l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1 - l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1 - - l.Dihedrals = [] - for i in range(l.dihedrals): - l.Dihedrals.append([0,0,0,0,0]) - for i in range(self.NPHIH): - l.Dihedrals[i][0] = self.ICPH[i] - l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1 - l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1 - l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1 - l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1 - for i in range(self.NPHIA): - l.Dihedrals[self.NPHIH + i][0] = self.ICP[i] - l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1 - l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1 - l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1 - l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1 - - print 'done.' - return l - else: - print '(Error: Not all the Amber data has been read!)' - - #-------------------------------------------------------- - - def Read_data(self, Filename): - 'Read the filename, returning a list of strings' - - import string, sys - - print 'Reading', Filename + '...', - sys.stdout.flush() - - try: - F = open(Filename) - except IOError, Detail: - print '(error:', Detail[1] + '!)' - return - - try: - Lines = F.readlines() - except IOError, Detail: - print '(error:', Detail[1] + '!)' - F.close() - return - - F.close() - - # If the first line is empty, use the Basename - if Filename[-4:] == '.crd': - if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file - Basename = Filename[:string.find(Filename, '.')] - Item_list = [Basename] - print 'Warning: Title not present... Assigning Basename as Title' - else: - Item_list = [] - else: - if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file - Basename = Filename[:string.find(Filename, '.')] - Item_list = [Basename] - print 'Warning: Title not present... Assigning Basename as Title' - else: - Item_list = [] - - for Line in Lines: - if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file. - Item_list.extend(string.split(Line)) - - return Item_list - - #-------------------------------------------------------- - - def Read_CRD(self, Basename): - 'Read the Amber coordinate/restart (.crd) file' - - # The optional velocities and periodic box size are not yet parsed. - - Item_list = self.Read_data(Basename + '.crd') - - if Item_list == None: - return - elif len(Item_list) < 2: - print '(error: File too short!)' - return - - # Parse the data - if self.__dict__.has_key('ITITL'): - if Pop(Item_list,0) != self.ITITL: - print '(warning: ITITL differs!)', - else: - self.ITITL = Pop(Item_list,0) - print self.ITITL #Vikas Modification : Priting the Title - - if self.__dict__.has_key('NATOM'): - if eval(Pop(Item_list,0)) != self.NATOM: - print '(error: NATOM differs!)' - return - else: - self.NATOM = eval(Pop(Item_list,0)) - print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value. - - #if len(Item_list) == 1 + 3 * self.NATOM: - # Vikas' Modification: I changed the condition. - if (len(Item_list)%3) != 0: - self.TIME = eval(Pop(Item_list,0)) - else: - self.TIME = 0 - print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value. - if len(Item_list) < 3 * self.NATOM: - print '(error: File too short!)' - return - - self.X = [] - self.Y = [] - self.Z = [] - for i in range(self.NATOM): - self.X.append(eval(Pop(Item_list,0))) - self.Y.append(eval(Pop(Item_list,0))) - self.Z.append(eval(Pop(Item_list,0))) - - if (self.NATOM == 1) and len(Item_list): - print '(warning: Ambiguity!)', - - if len(Item_list) >= 3 * self.NATOM: - self.VX = [] - self.VY = [] - self.VZ = [] - for i in range(self.NATOM): - self.VX.append(eval(Pop(Item_list,0))) - self.VY.append(eval(Pop(Item_list,0))) - self.VZ.append(eval(Pop(Item_list,0))) - - if len(Item_list) >= 3: - self.BOX = [] - for i in range(3): - self.BOX.append(eval(Pop(Item_list,0))) - - if len(Item_list): - print '(warning: File too large!)', - - print 'done.' - self.CRD_is_read = 1 - - #-------------------------------------------------------- - - def Read_TOP(self, Basename): - 'Read the Amber parameter/topology (.top) file' - Item_list = self.Read_data(Basename + '.top') - - if Item_list == None: - return - elif len(Item_list) < 31: - print '(error: File too short!)' - return - - # Parse the data - if self.__dict__.has_key('ITITL'): - if Pop(Item_list,0) != self.ITITL: - print '(warning: ITITL differs!)' - else: - self.ITITL = Pop(Item_list,0) - print self.ITITL # Printing Self Title - - if self.__dict__.has_key('NATOM'): - if eval(Pop(Item_list,0)) != self.NATOM: - print '(error: NATOM differs!)' - return - else: - self.NATOM = eval(Pop(Item_list,0)) - print self.NATOM # Printing total number of atoms just to make sure that thing are going right - self.NTYPES = eval(Pop(Item_list,0)) - self.NBONH = eval(Pop(Item_list,0)) - self.MBONA = eval(Pop(Item_list,0)) - self.NTHETH = eval(Pop(Item_list,0)) - self.MTHETA = eval(Pop(Item_list,0)) - self.NPHIH = eval(Pop(Item_list,0)) - self.MPHIA = eval(Pop(Item_list,0)) - self.NHPARM = eval(Pop(Item_list,0)) - self.NPARM = eval(Pop(Item_list,0)) - self.NEXT = eval(Pop(Item_list,0)) - self.NRES = eval(Pop(Item_list,0)) - self.NBONA = eval(Pop(Item_list,0)) - self.NTHETA = eval(Pop(Item_list,0)) - self.NPHIA = eval(Pop(Item_list,0)) - self.NUMBND = eval(Pop(Item_list,0)) - self.NUMANG = eval(Pop(Item_list,0)) - self.NPTRA = eval(Pop(Item_list,0)) - self.NATYP = eval(Pop(Item_list,0)) - self.NPHB = eval(Pop(Item_list,0)) - self.IFPERT = eval(Pop(Item_list,0)) - self.NBPER = eval(Pop(Item_list,0)) - self.NGPER = eval(Pop(Item_list,0)) - self.NDPER = eval(Pop(Item_list,0)) - self.MBPER = eval(Pop(Item_list,0)) - self.MGPER = eval(Pop(Item_list,0)) - self.MDPER = eval(Pop(Item_list,0)) - self.IFBOX = eval(Pop(Item_list,0)) - self.NMXRS = eval(Pop(Item_list,0)) - self.IFCAP = eval(Pop(Item_list,0)) - - #.................................................... - - if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \ - 2*(self.NRES + self.NUMBND + self.NUMANG) + \ - 3*self.NPTRA + self.NATYP: - print '(error: File too short!)' - return -1 - - self.IGRAPH = [] - Pop(Item_list,0) - - # A little kludge is needed here, since the IGRAPH strings are - # not separated by spaces if 4 characters in length. - for i in range(self.NATOM): - if len(Item_list[0]) > 4: - Item_list.insert(1, Item_list[0][4:]) - Item_list.insert(1, Item_list[0][0:4]) - del Item_list[0] - self.IGRAPH.append(Pop(Item_list,0)) - - # Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file. - print 'Reading Charges...' - self.CHRG = [] - for i in range(self.NATOM): - self.CHRG.append(eval(Pop(Item_list,0))) - - print 'Reading Atomic Masses...' - self.AMASS = [] - for i in range(self.NATOM): - self.AMASS.append(eval(Pop(Item_list,0))) - - print 'Reading Atom Types...' - self.IAC = [] - for i in range(self.NATOM): - self.IAC.append(eval(Pop(Item_list,0))) - - print 'Reading Excluded Atoms...' - self.NUMEX = [] - for i in range(self.NATOM): - self.NUMEX.append(eval(Pop(Item_list,0))) - - print 'Reading Non-bonded Parameter Index...' - self.ICO = [] - for i in range(self.NTYPES**2): - self.ICO.append(eval(Pop(Item_list,0))) - - print 'Reading Residue Labels...' - self.LABRES = [] - for i in range(self.NRES): - self.LABRES.append(Pop(Item_list,0)) - - print 'Reading Residues Starting Pointers...' - self.IPRES = [] - for i in range(self.NRES): - self.IPRES.append(eval(Pop(Item_list,0))) - - print 'Reading Bond Force Constants...' - self.RK = [] - for i in range(self.NUMBND): - self.RK.append(eval(Pop(Item_list,0))) - - print 'Reading Equilibrium Bond Values...' - self.REQ = [] - for i in range(self.NUMBND): - self.REQ.append(eval(Pop(Item_list,0))) - - print 'Reading Angle Force Constants...' - self.TK = [] - for i in range(self.NUMANG): - self.TK.append(eval(Pop(Item_list,0))) - - print 'Reading Equilibrium Angle Values...' - self.TEQ = [] - for i in range(self.NUMANG): - self.TEQ.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedral Force Constants...' - self.PK = [] - for i in range(self.NPTRA): - self.PK.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedral Periodicity...' - self.PN = [] - for i in range(self.NPTRA): - self.PN.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedral Phase...' - self.PHASE = [] - for i in range(self.NPTRA): - self.PHASE.append(eval(Pop(Item_list,0))) - - print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though - self.SOLTY = [] - for i in range(self.NATYP): - self.SOLTY.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2: - print '(error: File too short!)' - return -1 - - print 'Reading LJ A Coefficient...' - self.CN1 = [] - for i in range(self.NTYPES * (self.NTYPES + 1) / 2): - self.CN1.append(eval(Pop(Item_list,0))) - - print 'Reading LJ B Coefficient...' - self.CN2 = [] - for i in range(self.NTYPES * (self.NTYPES + 1) / 2): - self.CN2.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \ - 4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA): - print '(error: File too short!)' - return -1 - - print 'Reading Bonds which include hydrogen...' - self.IBH = [] - self.JBH = [] - self.ICBH = [] - for i in range(self.NBONH): - self.IBH.append(eval(Pop(Item_list,0))) - self.JBH.append(eval(Pop(Item_list,0))) - self.ICBH.append(eval(Pop(Item_list,0))) - - print 'Reading Bonds which dont include hydrogen...' - self.IB = [] - self.JB = [] - self.ICB = [] - for i in range(self.NBONA): - self.IB.append(eval(Pop(Item_list,0))) - self.JB.append(eval(Pop(Item_list,0))) - self.ICB.append(eval(Pop(Item_list,0))) - - print 'Reading Angles which include hydrogen...' - self.ITH = [] - self.JTH = [] - self.KTH = [] - self.ICTH = [] - for i in range(self.NTHETH): - self.ITH.append(eval(Pop(Item_list,0))) - self.JTH.append(eval(Pop(Item_list,0))) - self.KTH.append(eval(Pop(Item_list,0))) - self.ICTH.append(eval(Pop(Item_list,0))) - - print 'Reading Angles which dont include hydrogen...' - self.IT = [] - self.JT = [] - self.KT = [] - self.ICT = [] - for i in range(self.NTHETA): - self.IT.append(eval(Pop(Item_list,0))) - self.JT.append(eval(Pop(Item_list,0))) - self.KT.append(eval(Pop(Item_list,0))) - self.ICT.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedrals which include hydrogen...' - self.IPH = [] - self.JPH = [] - self.KPH = [] - self.LPH = [] - self.ICPH = [] - for i in range(self.NPHIH): - self.IPH.append(eval(Pop(Item_list,0))) - self.JPH.append(eval(Pop(Item_list,0))) - self.KPH.append(eval(Pop(Item_list,0))) - self.LPH.append(eval(Pop(Item_list,0))) - self.ICPH.append(eval(Pop(Item_list,0))) - - print 'Reading Dihedrals which dont include hydrogen...' - self.IP = [] - self.JP = [] - self.KP = [] - self.LP = [] - self.ICP = [] - for i in range(self.NPHIA): - self.IP.append(eval(Pop(Item_list,0))) - self.JP.append(eval(Pop(Item_list,0))) - self.KP.append(eval(Pop(Item_list,0))) - self.LP.append(eval(Pop(Item_list,0))) - self.ICP.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM: - print '(error: File too short!)' - return -1 - - print 'Reading Excluded Atom List...' - self.NATEX = [] - for i in range(self.NEXT): - self.NATEX.append(eval(Pop(Item_list,0))) - - print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...' - self.ASOL = [] - for i in range(self.NPHB): - self.ASOL.append(eval(Pop(Item_list,0))) - - print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...' - self.BSOL = [] - for i in range(self.NPHB): - self.BSOL.append(eval(Pop(Item_list,0))) - - print 'Reading H-Bond Cut...' # I think it is not being used nowadays - self.HBCUT = [] - for i in range(self.NPHB): - self.HBCUT.append(eval(Pop(Item_list,0))) - - print 'Reading Amber Atom Types for each atom...' - self.ISYMBL = [] - for i in range(self.NATOM): - self.ISYMBL.append(Pop(Item_list,0)) - - print 'Reading Tree Chain Classification...' - self.ITREE = [] - for i in range(self.NATOM): - self.ITREE.append(Pop(Item_list,0)) - - print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module - self.JOIN = [] - for i in range(self.NATOM): - self.JOIN.append(eval(Pop(Item_list,0))) - - print 'Reading IRotate...' # Currently unused in Sander and Gibbs - self.IROTAT = [] - for i in range(self.NATOM): - self.IROTAT.append(eval(Pop(Item_list,0))) - - #.................................................... - - if self.IFBOX > 0: - if len(Item_list) < 3: - print '(error: File too short!)' - return -1 - - print 'Reading final residue which is part of solute...' - self.IPTRES = eval(Pop(Item_list,0)) - print 'Reading total number of molecules...' - self.NSPM = eval(Pop(Item_list,0)) - print 'Reading first solvent moleule index...' - self.NSPSOL = eval(Pop(Item_list,0)) - - if len(Item_list) < self.NSPM + 4: - print '(error: File too short!)' - return -1 - - print 'Reading atom per molecule...' - self.NSP = [] - for i in range(self.NSPM): - self.NSP.append(eval(Pop(Item_list,0))) - - self.BETA = eval(Pop(Item_list,0)) - - print 'Reading Box Dimensions...' - if self.__dict__.has_key('BOX'): - BOX = [] - for i in range(3): - BOX.append(eval(Pop(Item_list,0))) - for i in range(3): - if BOX[i] != self.BOX[i]: - print '(warning: BOX differs!)', - break - del BOX - else: - self.BOX = [] - for i in range(3): - self.BOX.append(eval(Pop(Item_list,0))) - - #.................................................... - - if self.IFCAP > 0: - if len(Item_list) < 5: - print '(error: File too short!)' - return -1 - print 'Reading ICAP variables::: For details, refer to online AMBER format manual' - self.NATCAP = eval(Pop(Item_list,0)) - self.CUTCAP = eval(Pop(Item_list,0)) - self.XCAP = eval(Pop(Item_list,0)) - self.YCAP = eval(Pop(Item_list,0)) - self.ZCAP = eval(Pop(Item_list,0)) - - #.................................................... - - if self.IFPERT > 0: - if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \ - 6 * self.NDPER + self.NRES + 6 * self.NATOM: - print '(error: File too short!)' - return -1 - - print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual' - self.IBPER = [] - self.JBPER = [] - for i in range(self.NBPER): - self.IBPER.append(eval(Pop(Item_list,0))) - self.JBPER.append(eval(Pop(Item_list,0))) - - self.ICBPER = [] - for i in range(2 * self.NBPER): - self.ICBPER.append(eval(Pop(Item_list,0))) - - self.ITPER = [] - self.JTPER = [] - self.KTPER = [] - for i in range(self.NGPER): - self.ITPER.append(eval(Pop(Item_list,0))) - self.JTPER.append(eval(Pop(Item_list,0))) - self.KTPER.append(eval(Pop(Item_list,0))) - - self.ICTPER = [] - for i in range(2 * self.NGPER): - self.ICTPER.append(eval(Pop(Item_list,0))) - - self.IPPER = [] - self.JPPER = [] - self.KPPER = [] - self.LPPER = [] - for i in range(self.NDPER): - self.IPPER.append(eval(Pop(Item_list,0))) - self.JPPER.append(eval(Pop(Item_list,0))) - self.KPPER.append(eval(Pop(Item_list,0))) - self.LPPER.append(eval(Pop(Item_list,0))) - - self.ICPPER = [] - for i in range(2 * self.NDPER): - self.ICPPER.append(eval(Pop(Item_list,0))) - - LABRES = [] - for i in range(self.NRES): - LABRES.append(Pop(Item_list,0)) - for i in range(self.NRES): - if LABRES[i] != self.LABRES[i]: - print '(warning: BOX differs!)', - break - - self.IGRPER = [] - for i in range(self.NATOM): - self.IGRPER.append(eval(Pop(Item_list,0))) - - self.ISMPER = [] - for i in range(self.NATOM): - self.ISMPER.append(eval(Pop(Item_list,0))) - - self.ALMPER = [] - for i in range(self.NATOM): - self.ALMPER.append(eval(Pop(Item_list,0))) - - self.IAPER = [] - for i in range(self.NATOM): - self.IAPER.append(eval(Pop(Item_list,0))) - - self.IACPER = [] - for i in range(self.NATOM): - self.IACPER.append(eval(Pop(Item_list,0))) - - self.CGPER = [] - for i in range(self.NATOM): - self.CGPER.append(eval(Pop(Item_list,0))) - - #.................................................... - - self.IPOL = 0 - if self.IPOL == 1: - if len(Item_list) < self.NATOM: - print '(error: File too short!)' - return -1 - print 'Reading Polarizability Data. For details, refer to online AMBER format manual' - self.ATPOL = [] - for i in range(self.NATOM): - self.ATPOL.append(eval(Pop(Item_list,0))) - - if self.IFPERT == 1: - if len(Item_list) < self.NATOM: - print '(error: File too short!)' - return -1 - self.ATPOL1 = [] - for i in range(self.NATOM): - self.ATPOL1.append(eval(Pop(Item_list,0))) - - #.................................................... - - if len(Item_list): - print '(warning: File too large!)', - - print 'done.' - self.TOP_is_read = 1 - -#============================================================ - -def Find_Amber_files(): - 'Look for sets of Amber files to process' - '''If not passed anything on the command line, look for pairs of - Amber files (.crd and .top) in the current directory. For - each set if there is no corresponding Lammps file (data.), or it is - older than any of the Amber files, add its basename to a list of - strings. This list is returned by the function''' - - # Date and existence checks not yet implemented - - import os, sys - - Basename_list = [] - - # Extract basenames from command line - for Name in sys.argv[1:]: - if Name[-4:] == '.crd': - Basename_list.append(Name[:-4]) - else: - if Name[-4:] == '.top': - Basename_list.append(Name[:-4]) - else: - Basename_list.append(Name) - - # Remove duplicate basenames - for Basename in Basename_list[:]: - while Basename_list.count(Basename) > 1: - Basename_list.remove(Basename) - - if Basename_list == []: - print 'Looking for Amber files...', - Dir_list = os.listdir('.') - Dir_list.sort() - for File in Dir_list: - if File[-4:] == '.top': - Basename = File[:-4] - if (Basename + '.crd') in Dir_list: - Basename_list.append(Basename) - if Basename_list != []: - print 'found', - for i in range(len(Basename_list)-1): - print Basename_list[i] + ',', - print Basename_list[-1] + '\n' - - if Basename_list == []: - print 'none.\n' - - return Basename_list - -#============================================================ - -def Convert_Amber_files(): - 'Handle the whole conversion process' - print - print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!' - print - Basename_list = Find_Amber_files() - for Basename in Basename_list: - a = Amber() - a.Read_CRD(Basename) - if a.CRD_is_read: - a.Read_TOP(Basename) - if a.TOP_is_read: - l = a.Coerce_to_Lammps() - l.Write_Lammps(Basename) - del l - del a - print - -#============================================================ - -Convert_Amber_files() +#! /usr/bin/python + +# +# This is amber2lammps, a program written by Keir E. Novik to convert +# Amber files to Lammps files. +# +# Copyright 1999, 2000 Keir E. Novik; all rights reserved. +# +# Modified by Vikas Varshney, U Akron, 5 July 2005, as described in README +# Bug Fixed :Third argument in Dihedral Coeffs section is an integer - Ketan S Khare September 26, 2011 + +#============================================================ + +def Pop(S, I=-1): + 'Pop item I from list' + X = S[I] + del S[I] + return X + +#============================================================ + +class Lammps: + + #-------------------------------------------------------- + + def Dump(self): + 'Write out contents of self (intended for debugging)' + Name_list = self.__dict__.keys() + Name_list.sort() + for Name in Name_list: + print Name + ':', self.__dict__[Name] + + #-------------------------------------------------------- + + def Write_data(self, Basename, Item_list): + 'Write the Lammps data to file (used by Write_Lammps)' + import os, sys + + Filename = 'data.' + Basename + + Dir_list = os.listdir('.') + i = 1 + while Filename in Dir_list: + Filename = 'data' + `i` + '.' + Basename + i = i +1 + del i + + print 'Writing', Filename + '...', + sys.stdout.flush() + + try: + F = open(Filename, 'w') + except IOError, Detail: + print '(error:', Detail[1] + '!)' + return + + try: + F.writelines(Item_list) + except IOError, Detail: + print '(error:', Detail[1] + '!)' + F.close() + return + + F.close() + print 'done.' + + #-------------------------------------------------------- + + def Write_Lammps(self, Basename): + 'Write the Lammps data file, ignoring blank sections' + import string + L = [] + + L.append('LAMMPS data file for ' + self.name + '\n\n') + + L.append(`self.atoms` + ' atoms\n') + L.append(`self.bonds` + ' bonds\n') + L.append(`self.angles` + ' angles\n') + L.append(`self.dihedrals` + ' dihedrals\n') + L.append(`self.impropers` + ' impropers\n\n') + + L.append(`self.atom_types` + ' atom types\n') + if self.bonds > 0: + L.append(`self.bond_types` + ' bond types\n') + if self.angles > 0: + L.append(`self.angle_types` + ' angle types\n') + if self.dihedrals > 0: + L.append(`self.dihedral_types` + ' dihedral types\n') + L.append('\n') + + L.append(`self.xlo` + ' ' + `self.xhi` + ' xlo xhi\n') + L.append(`self.ylo` + ' ' + `self.yhi` + ' ylo yhi\n') + L.append(`self.zlo` + ' ' + `self.zhi` + ' zlo zhi\n\n') + + if self.atom_types != 0: + L.append('Masses\n\n') + for i in range(self.atom_types): + L.append(`i+1` + ' ' + `self.Masses[i]` + '\n') + L.append('\n') + + L.append('Pair Coeffs\n\n') + for i in range(self.atom_types): + L.append(`i+1`) + for j in range(len(self.Nonbond_Coeffs[0])): + L.append(' ' + `self.Nonbond_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.bonds != 0 and self.bond_types != 0: + L.append('Bond Coeffs\n\n') + for i in range(self.bond_types): + L.append(`i+1`) + for j in range(len(self.Bond_Coeffs[0])): + L.append(' ' + `self.Bond_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.angles != 0 and self.angle_types != 0: + L.append('Angle Coeffs\n\n') + for i in range(self.angle_types): + L.append(`i+1`) + for j in range(len(self.Angle_Coeffs[0])): + L.append(' ' + `self.Angle_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.dihedrals != 0 and self.dihedral_types != 0: + L.append('Dihedral Coeffs\n\n') + for i in range(self.dihedral_types): + L.append(`i+1`) + for j in range(len(self.Dihedral_Coeffs[0])): + L.append(' ' + `self.Dihedral_Coeffs[i][j]`) + L.append('\n') + L.append('\n') + + if self.atoms != 0: + L.append('Atoms\n\n') + for i in range(self.atoms): + L.append(`i+1`) + for j in range(len(self.Atoms[0])): + L.append(' ' + `self.Atoms[i][j]`) + L.append('\n') + L.append('\n') + + if self.bonds != 0 and self.bond_types != 0: + L.append('Bonds\n\n') + for i in range(self.bonds): + L.append(`i+1`) + for j in range(len(self.Bonds[0])): + L.append(' ' + `self.Bonds[i][j]`) + L.append('\n') + L.append('\n') + + if self.angles != 0 and self.angle_types != 0: + L.append('Angles\n\n') + for i in range(self.angles): + L.append(`i+1`) + for j in range(len(self.Angles[0])): + L.append(' ' + `self.Angles[i][j]`) + L.append('\n') + L.append('\n') + + if self.dihedrals != 0 and self.dihedral_types != 0: + L.append('Dihedrals\n\n') + for i in range(self.dihedrals): + L.append(`i+1`) + for j in range(len(self.Dihedrals[0])): + L.append(' ' + `self.Dihedrals[i][j]`) + L.append('\n') + L.append('\n') + + self.Write_data(Basename, L) + +#============================================================ + +class Amber: + def __init__(self): + 'Initialise the Amber class' + self.CRD_is_read = 0 + self.TOP_is_read = 0 + + #-------------------------------------------------------- + + def Dump(self): + 'Write out contents of self (intended for debugging)' + Name_list = self.__dict__.keys() + Name_list.sort() + for Name in Name_list: + print Name + ':', self.__dict__[Name] + + #-------------------------------------------------------- + + def Coerce_to_Lammps(self): + 'Return the Amber data converted to Lammps format' + + import math + + if self.CRD_is_read and self.TOP_is_read: + l = Lammps() + print 'Converting...', + + l.name = self.ITITL + l.atoms = self.NATOM + l.bonds = self.NBONH + self.MBONA + l.angles = self.NTHETH + self.MTHETA + l.dihedrals = self.NPHIH + self.MPHIA + l.impropers = 0 + l.atom_types = self.NTYPES + l.bond_types = self.NUMBND + l.angle_types = self.NUMANG + l.dihedral_types = self.NPTRA + + Shift = 0 + if self.__dict__.has_key('BOX'): + l.xlo = 0.0 + l.xhi = self.BOX[0] + l.ylo = 0.0 + l.yhi = self.BOX[1] + l.zlo = 0.0 + l.zhi = self.BOX[2] + if (l.xlo > min(self.X)) or (l.xhi < max(self.X)) or \ + (l.ylo > min(self.Y)) or (l.yhi < max(self.Y)) or \ + (l.zlo > min(self.Z)) or (l.zhi < max(self.Z)): + # Vikas Modification: Disabling Shifting. This means I am intend to send exact coordinates of each atom and let LAMMPS + # take care of imaging into periodic image cells. If one wants to shift all atoms in the periodic box, + # please uncomment the below 2 lines. + print '(warning: Currently not shifting the atoms to the periodic box)' + #Shift = 1 + else: + print '(warning: Guessing at periodic box!)', + l.xlo = min(self.X) + l.xhi = max(self.X) + l.ylo = min(self.Y) + l.yhi = max(self.Y) + l.zlo = min(self.Z) + l.zhi = max(self.Z) + + # This doesn't check duplicate values + l.Masses = [] + for i in range(l.atom_types): + l.Masses.append(0) + for i in range(self.NATOM): + l.Masses[self.IAC[i] - 1] = self.AMASS[i] + + l.Nonbond_Coeffs = [] + for i in range(self.NTYPES): + l.Nonbond_Coeffs.append([0,0]) + for i in range(self.NTYPES): + j = self.ICO[i * (self.NTYPES + 1)] - 1 + if self.CN1[j] == 0.0: + l.Nonbond_Coeffs[i][0] = 0.0 + else: + l.Nonbond_Coeffs[i][0] = \ + 0.25 * (self.CN2[j])**2 / self.CN1[j] + if self.CN2[j] == 0.0: + l.Nonbond_Coeffs[i][1] = 0.0 + else: + l.Nonbond_Coeffs[i][1] = \ + (self.CN1[j] / self.CN2[j])**(1.0/6.0) + + l.Bond_Coeffs = [] + for i in range(self.NUMBND): + l.Bond_Coeffs.append([0,0]) + for i in range(self.NUMBND): + l.Bond_Coeffs[i][0] = self.RK[i] + l.Bond_Coeffs[i][1] = self.REQ[i] + + l.Angle_Coeffs = [] + for i in range(self.NUMANG): + l.Angle_Coeffs.append([0,0]) + for i in range(self.NUMANG): + l.Angle_Coeffs[i][0] = self.TK[i] + l.Angle_Coeffs[i][1] = (180/math.pi) * self.TEQ[i] + + l.Dihedral_Coeffs = [] + for i in range(self.NPTRA): + l.Dihedral_Coeffs.append([0,0,0]) + for i in range(self.NPTRA): + l.Dihedral_Coeffs[i][0] = self.PK[i] + if self.PHASE[i] == 0: + l.Dihedral_Coeffs[i][1] = 1 + else: + l.Dihedral_Coeffs[i][1] = -1 + l.Dihedral_Coeffs[i][2] = int(self.PN[i]) + + l.Atoms = [] + for i in range(self.NATOM): + x = self.X[i] + y = self.Y[i] + z = self.Z[i] + if Shift: + while x < l.xlo: + x = x + self.BOX[0] + while x > l.xhi: + x = x - self.BOX[0] + while y < l.ylo: + y = y + self.BOX[1] + while y > l.yhi: + y = y - self.BOX[1] + while z < l.zlo: + z = z + self.BOX[2] + while z > l.zhi: + z = z - self.BOX[2] + l.Atoms.append([0, self.IAC[i], self.CHRG[i]/18.2223, \ + x, y, z]) + + l.Bonds = [] + for i in range(l.bonds): + l.Bonds.append([0,0,0]) + for i in range(self.NBONH): + l.Bonds[i][0] = self.ICBH[i] + l.Bonds[i][1] = abs(self.IBH[i])/3 + 1 + l.Bonds[i][2] = abs(self.JBH[i])/3 + 1 + for i in range(self.NBONA): + l.Bonds[self.NBONH + i][0] = self.ICB[i] + l.Bonds[self.NBONH + i][1] = abs(self.IB[i])/3 + 1 + l.Bonds[self.NBONH + i][2] = abs(self.JB[i])/3 + 1 + + l.Angles = [] + for i in range(l.angles): + l.Angles.append([0,0,0,0]) + for i in range(self.NTHETH): + l.Angles[i][0] = self.ICTH[i] + l.Angles[i][1] = abs(self.ITH[i])/3 + 1 + l.Angles[i][2] = abs(self.JTH[i])/3 + 1 + l.Angles[i][3] = abs(self.KTH[i])/3 + 1 + for i in range(self.NTHETA): + l.Angles[self.NTHETH + i][0] = self.ICT[i] + l.Angles[self.NTHETH + i][1] = abs(self.IT[i])/3 + 1 + l.Angles[self.NTHETH + i][2] = abs(self.JT[i])/3 + 1 + l.Angles[self.NTHETH + i][3] = abs(self.KT[i])/3 + 1 + + l.Dihedrals = [] + for i in range(l.dihedrals): + l.Dihedrals.append([0,0,0,0,0]) + for i in range(self.NPHIH): + l.Dihedrals[i][0] = self.ICPH[i] + l.Dihedrals[i][1] = abs(self.IPH[i])/3 + 1 + l.Dihedrals[i][2] = abs(self.JPH[i])/3 + 1 + l.Dihedrals[i][3] = abs(self.KPH[i])/3 + 1 + l.Dihedrals[i][4] = abs(self.LPH[i])/3 + 1 + for i in range(self.NPHIA): + l.Dihedrals[self.NPHIH + i][0] = self.ICP[i] + l.Dihedrals[self.NPHIH + i][1] = abs(self.IP[i])/3 + 1 + l.Dihedrals[self.NPHIH + i][2] = abs(self.JP[i])/3 + 1 + l.Dihedrals[self.NPHIH + i][3] = abs(self.KP[i])/3 + 1 + l.Dihedrals[self.NPHIH + i][4] = abs(self.LP[i])/3 + 1 + + print 'done.' + return l + else: + print '(Error: Not all the Amber data has been read!)' + + #-------------------------------------------------------- + + def Read_data(self, Filename): + 'Read the filename, returning a list of strings' + + import string, sys + + print 'Reading', Filename + '...', + sys.stdout.flush() + + try: + F = open(Filename) + except IOError, Detail: + print '(error:', Detail[1] + '!)' + return + + try: + Lines = F.readlines() + except IOError, Detail: + print '(error:', Detail[1] + '!)' + F.close() + return + + F.close() + + # If the first line is empty, use the Basename + if Filename[-4:] == '.crd': + if string.split(Lines[0]) == []: # This line corresponds to TITLE name in CRD file + Basename = Filename[:string.find(Filename, '.')] + Item_list = [Basename] + print 'Warning: Title not present... Assigning Basename as Title' + else: + Item_list = [] + else: + if string.split(Lines[3]) == []: # This line corresponds to TITLE name in TOPOLOGY file + Basename = Filename[:string.find(Filename, '.')] + Item_list = [Basename] + print 'Warning: Title not present... Assigning Basename as Title' + else: + Item_list = [] + + for Line in Lines: + if Line[0]!='%': #Vikas' Modification: This condition ignores all the lines starting with % in the topology file. + Item_list.extend(string.split(Line)) + + return Item_list + + #-------------------------------------------------------- + + def Read_CRD(self, Basename): + 'Read the Amber coordinate/restart (.crd) file' + + # The optional velocities and periodic box size are not yet parsed. + + Item_list = self.Read_data(Basename + '.crd') + + if Item_list == None: + return + elif len(Item_list) < 2: + print '(error: File too short!)' + return + + # Parse the data + if self.__dict__.has_key('ITITL'): + if Pop(Item_list,0) != self.ITITL: + print '(warning: ITITL differs!)', + else: + self.ITITL = Pop(Item_list,0) + print self.ITITL #Vikas Modification : Priting the Title + + if self.__dict__.has_key('NATOM'): + if eval(Pop(Item_list,0)) != self.NATOM: + print '(error: NATOM differs!)' + return + else: + self.NATOM = eval(Pop(Item_list,0)) + print self.NATOM # Vikas' Modification: Printing number of atoms just to make sure that the program is reading the correct value. + + #if len(Item_list) == 1 + 3 * self.NATOM: + # Vikas' Modification: I changed the condition. + if (len(Item_list)%3) != 0: + self.TIME = eval(Pop(Item_list,0)) + else: + self.TIME = 0 + print self.TIME # Vikas' Modification : Printing simulation time, just to make sure that the program is readint the correct value. + if len(Item_list) < 3 * self.NATOM: + print '(error: File too short!)' + return + + self.X = [] + self.Y = [] + self.Z = [] + for i in range(self.NATOM): + self.X.append(eval(Pop(Item_list,0))) + self.Y.append(eval(Pop(Item_list,0))) + self.Z.append(eval(Pop(Item_list,0))) + + if (self.NATOM == 1) and len(Item_list): + print '(warning: Ambiguity!)', + + if len(Item_list) >= 3 * self.NATOM: + self.VX = [] + self.VY = [] + self.VZ = [] + for i in range(self.NATOM): + self.VX.append(eval(Pop(Item_list,0))) + self.VY.append(eval(Pop(Item_list,0))) + self.VZ.append(eval(Pop(Item_list,0))) + + if len(Item_list) >= 3: + self.BOX = [] + for i in range(3): + self.BOX.append(eval(Pop(Item_list,0))) + + if len(Item_list): + print '(warning: File too large!)', + + print 'done.' + self.CRD_is_read = 1 + + #-------------------------------------------------------- + + def Read_TOP(self, Basename): + 'Read the Amber parameter/topology (.top) file' + Item_list = self.Read_data(Basename + '.top') + + if Item_list == None: + return + elif len(Item_list) < 31: + print '(error: File too short!)' + return + + # Parse the data + if self.__dict__.has_key('ITITL'): + if Pop(Item_list,0) != self.ITITL: + print '(warning: ITITL differs!)' + else: + self.ITITL = Pop(Item_list,0) + print self.ITITL # Printing Self Title + + if self.__dict__.has_key('NATOM'): + if eval(Pop(Item_list,0)) != self.NATOM: + print '(error: NATOM differs!)' + return + else: + self.NATOM = eval(Pop(Item_list,0)) + print self.NATOM # Printing total number of atoms just to make sure that thing are going right + self.NTYPES = eval(Pop(Item_list,0)) + self.NBONH = eval(Pop(Item_list,0)) + self.MBONA = eval(Pop(Item_list,0)) + self.NTHETH = eval(Pop(Item_list,0)) + self.MTHETA = eval(Pop(Item_list,0)) + self.NPHIH = eval(Pop(Item_list,0)) + self.MPHIA = eval(Pop(Item_list,0)) + self.NHPARM = eval(Pop(Item_list,0)) + self.NPARM = eval(Pop(Item_list,0)) + self.NEXT = eval(Pop(Item_list,0)) + self.NRES = eval(Pop(Item_list,0)) + self.NBONA = eval(Pop(Item_list,0)) + self.NTHETA = eval(Pop(Item_list,0)) + self.NPHIA = eval(Pop(Item_list,0)) + self.NUMBND = eval(Pop(Item_list,0)) + self.NUMANG = eval(Pop(Item_list,0)) + self.NPTRA = eval(Pop(Item_list,0)) + self.NATYP = eval(Pop(Item_list,0)) + self.NPHB = eval(Pop(Item_list,0)) + self.IFPERT = eval(Pop(Item_list,0)) + self.NBPER = eval(Pop(Item_list,0)) + self.NGPER = eval(Pop(Item_list,0)) + self.NDPER = eval(Pop(Item_list,0)) + self.MBPER = eval(Pop(Item_list,0)) + self.MGPER = eval(Pop(Item_list,0)) + self.MDPER = eval(Pop(Item_list,0)) + self.IFBOX = eval(Pop(Item_list,0)) + self.NMXRS = eval(Pop(Item_list,0)) + self.IFCAP = eval(Pop(Item_list,0)) + + #.................................................... + + if len(Item_list) < 5 * self.NATOM + self.NTYPES**2 + \ + 2*(self.NRES + self.NUMBND + self.NUMANG) + \ + 3*self.NPTRA + self.NATYP: + print '(error: File too short!)' + return -1 + + self.IGRAPH = [] + Pop(Item_list,0) + + # A little kludge is needed here, since the IGRAPH strings are + # not separated by spaces if 4 characters in length. + for i in range(self.NATOM): + if len(Item_list[0]) > 4: + Item_list.insert(1, Item_list[0][4:]) + Item_list.insert(1, Item_list[0][0:4]) + del Item_list[0] + self.IGRAPH.append(Pop(Item_list,0)) + + # Vikas' Modification : In the following section, I am printing out each quantity which is currently being read from the topology file. + print 'Reading Charges...' + self.CHRG = [] + for i in range(self.NATOM): + self.CHRG.append(eval(Pop(Item_list,0))) + + print 'Reading Atomic Masses...' + self.AMASS = [] + for i in range(self.NATOM): + self.AMASS.append(eval(Pop(Item_list,0))) + + print 'Reading Atom Types...' + self.IAC = [] + for i in range(self.NATOM): + self.IAC.append(eval(Pop(Item_list,0))) + + print 'Reading Excluded Atoms...' + self.NUMEX = [] + for i in range(self.NATOM): + self.NUMEX.append(eval(Pop(Item_list,0))) + + print 'Reading Non-bonded Parameter Index...' + self.ICO = [] + for i in range(self.NTYPES**2): + self.ICO.append(eval(Pop(Item_list,0))) + + print 'Reading Residue Labels...' + self.LABRES = [] + for i in range(self.NRES): + self.LABRES.append(Pop(Item_list,0)) + + print 'Reading Residues Starting Pointers...' + self.IPRES = [] + for i in range(self.NRES): + self.IPRES.append(eval(Pop(Item_list,0))) + + print 'Reading Bond Force Constants...' + self.RK = [] + for i in range(self.NUMBND): + self.RK.append(eval(Pop(Item_list,0))) + + print 'Reading Equilibrium Bond Values...' + self.REQ = [] + for i in range(self.NUMBND): + self.REQ.append(eval(Pop(Item_list,0))) + + print 'Reading Angle Force Constants...' + self.TK = [] + for i in range(self.NUMANG): + self.TK.append(eval(Pop(Item_list,0))) + + print 'Reading Equilibrium Angle Values...' + self.TEQ = [] + for i in range(self.NUMANG): + self.TEQ.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedral Force Constants...' + self.PK = [] + for i in range(self.NPTRA): + self.PK.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedral Periodicity...' + self.PN = [] + for i in range(self.NPTRA): + self.PN.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedral Phase...' + self.PHASE = [] + for i in range(self.NPTRA): + self.PHASE.append(eval(Pop(Item_list,0))) + + print 'Reading Solty...' #I think this is currently not used in AMBER. Check it out, though + self.SOLTY = [] + for i in range(self.NATYP): + self.SOLTY.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list) < 2 * self.NTYPES * (self.NTYPES + 1) / 2: + print '(error: File too short!)' + return -1 + + print 'Reading LJ A Coefficient...' + self.CN1 = [] + for i in range(self.NTYPES * (self.NTYPES + 1) / 2): + self.CN1.append(eval(Pop(Item_list,0))) + + print 'Reading LJ B Coefficient...' + self.CN2 = [] + for i in range(self.NTYPES * (self.NTYPES + 1) / 2): + self.CN2.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list) < 3 * (self.NBONH + self.NBONA) + \ + 4 * (self.NTHETH + self.NTHETA) + 5 * (self.NPHIH + self.NPHIA): + print '(error: File too short!)' + return -1 + + print 'Reading Bonds which include hydrogen...' + self.IBH = [] + self.JBH = [] + self.ICBH = [] + for i in range(self.NBONH): + self.IBH.append(eval(Pop(Item_list,0))) + self.JBH.append(eval(Pop(Item_list,0))) + self.ICBH.append(eval(Pop(Item_list,0))) + + print 'Reading Bonds which dont include hydrogen...' + self.IB = [] + self.JB = [] + self.ICB = [] + for i in range(self.NBONA): + self.IB.append(eval(Pop(Item_list,0))) + self.JB.append(eval(Pop(Item_list,0))) + self.ICB.append(eval(Pop(Item_list,0))) + + print 'Reading Angles which include hydrogen...' + self.ITH = [] + self.JTH = [] + self.KTH = [] + self.ICTH = [] + for i in range(self.NTHETH): + self.ITH.append(eval(Pop(Item_list,0))) + self.JTH.append(eval(Pop(Item_list,0))) + self.KTH.append(eval(Pop(Item_list,0))) + self.ICTH.append(eval(Pop(Item_list,0))) + + print 'Reading Angles which dont include hydrogen...' + self.IT = [] + self.JT = [] + self.KT = [] + self.ICT = [] + for i in range(self.NTHETA): + self.IT.append(eval(Pop(Item_list,0))) + self.JT.append(eval(Pop(Item_list,0))) + self.KT.append(eval(Pop(Item_list,0))) + self.ICT.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedrals which include hydrogen...' + self.IPH = [] + self.JPH = [] + self.KPH = [] + self.LPH = [] + self.ICPH = [] + for i in range(self.NPHIH): + self.IPH.append(eval(Pop(Item_list,0))) + self.JPH.append(eval(Pop(Item_list,0))) + self.KPH.append(eval(Pop(Item_list,0))) + self.LPH.append(eval(Pop(Item_list,0))) + self.ICPH.append(eval(Pop(Item_list,0))) + + print 'Reading Dihedrals which dont include hydrogen...' + self.IP = [] + self.JP = [] + self.KP = [] + self.LP = [] + self.ICP = [] + for i in range(self.NPHIA): + self.IP.append(eval(Pop(Item_list,0))) + self.JP.append(eval(Pop(Item_list,0))) + self.KP.append(eval(Pop(Item_list,0))) + self.LP.append(eval(Pop(Item_list,0))) + self.ICP.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list) < self.NEXT + 3 * self.NPHB + 4 * self.NATOM: + print '(error: File too short!)' + return -1 + + print 'Reading Excluded Atom List...' + self.NATEX = [] + for i in range(self.NEXT): + self.NATEX.append(eval(Pop(Item_list,0))) + + print 'Reading H-Bond A Coefficient, corresponding to r**12 term for all possible types...' + self.ASOL = [] + for i in range(self.NPHB): + self.ASOL.append(eval(Pop(Item_list,0))) + + print 'Reading H-Bond B Coefficient, corresponding to r**10 term for all possible types...' + self.BSOL = [] + for i in range(self.NPHB): + self.BSOL.append(eval(Pop(Item_list,0))) + + print 'Reading H-Bond Cut...' # I think it is not being used nowadays + self.HBCUT = [] + for i in range(self.NPHB): + self.HBCUT.append(eval(Pop(Item_list,0))) + + print 'Reading Amber Atom Types for each atom...' + self.ISYMBL = [] + for i in range(self.NATOM): + self.ISYMBL.append(Pop(Item_list,0)) + + print 'Reading Tree Chain Classification...' + self.ITREE = [] + for i in range(self.NATOM): + self.ITREE.append(Pop(Item_list,0)) + + print 'Reading Join Array: Tree joining information' # Currently unused in Sander, an AMBER module + self.JOIN = [] + for i in range(self.NATOM): + self.JOIN.append(eval(Pop(Item_list,0))) + + print 'Reading IRotate...' # Currently unused in Sander and Gibbs + self.IROTAT = [] + for i in range(self.NATOM): + self.IROTAT.append(eval(Pop(Item_list,0))) + + #.................................................... + + if self.IFBOX > 0: + if len(Item_list) < 3: + print '(error: File too short!)' + return -1 + + print 'Reading final residue which is part of solute...' + self.IPTRES = eval(Pop(Item_list,0)) + print 'Reading total number of molecules...' + self.NSPM = eval(Pop(Item_list,0)) + print 'Reading first solvent moleule index...' + self.NSPSOL = eval(Pop(Item_list,0)) + + if len(Item_list) < self.NSPM + 4: + print '(error: File too short!)' + return -1 + + print 'Reading atom per molecule...' + self.NSP = [] + for i in range(self.NSPM): + self.NSP.append(eval(Pop(Item_list,0))) + + self.BETA = eval(Pop(Item_list,0)) + + print 'Reading Box Dimensions...' + if self.__dict__.has_key('BOX'): + BOX = [] + for i in range(3): + BOX.append(eval(Pop(Item_list,0))) + for i in range(3): + if BOX[i] != self.BOX[i]: + print '(warning: BOX differs!)', + break + del BOX + else: + self.BOX = [] + for i in range(3): + self.BOX.append(eval(Pop(Item_list,0))) + + #.................................................... + + if self.IFCAP > 0: + if len(Item_list) < 5: + print '(error: File too short!)' + return -1 + print 'Reading ICAP variables::: For details, refer to online AMBER format manual' + self.NATCAP = eval(Pop(Item_list,0)) + self.CUTCAP = eval(Pop(Item_list,0)) + self.XCAP = eval(Pop(Item_list,0)) + self.YCAP = eval(Pop(Item_list,0)) + self.ZCAP = eval(Pop(Item_list,0)) + + #.................................................... + + if self.IFPERT > 0: + if len(Item_list) < 4 * self.NBPER + 5 * self.NGPER + \ + 6 * self.NDPER + self.NRES + 6 * self.NATOM: + print '(error: File too short!)' + return -1 + + print 'Reading perturb variables, 1. Bond, 2. Angles, 3. Dihedrals, etc etc.::: For details, refer to online AMBER format manual' + self.IBPER = [] + self.JBPER = [] + for i in range(self.NBPER): + self.IBPER.append(eval(Pop(Item_list,0))) + self.JBPER.append(eval(Pop(Item_list,0))) + + self.ICBPER = [] + for i in range(2 * self.NBPER): + self.ICBPER.append(eval(Pop(Item_list,0))) + + self.ITPER = [] + self.JTPER = [] + self.KTPER = [] + for i in range(self.NGPER): + self.ITPER.append(eval(Pop(Item_list,0))) + self.JTPER.append(eval(Pop(Item_list,0))) + self.KTPER.append(eval(Pop(Item_list,0))) + + self.ICTPER = [] + for i in range(2 * self.NGPER): + self.ICTPER.append(eval(Pop(Item_list,0))) + + self.IPPER = [] + self.JPPER = [] + self.KPPER = [] + self.LPPER = [] + for i in range(self.NDPER): + self.IPPER.append(eval(Pop(Item_list,0))) + self.JPPER.append(eval(Pop(Item_list,0))) + self.KPPER.append(eval(Pop(Item_list,0))) + self.LPPER.append(eval(Pop(Item_list,0))) + + self.ICPPER = [] + for i in range(2 * self.NDPER): + self.ICPPER.append(eval(Pop(Item_list,0))) + + LABRES = [] + for i in range(self.NRES): + LABRES.append(Pop(Item_list,0)) + for i in range(self.NRES): + if LABRES[i] != self.LABRES[i]: + print '(warning: BOX differs!)', + break + + self.IGRPER = [] + for i in range(self.NATOM): + self.IGRPER.append(eval(Pop(Item_list,0))) + + self.ISMPER = [] + for i in range(self.NATOM): + self.ISMPER.append(eval(Pop(Item_list,0))) + + self.ALMPER = [] + for i in range(self.NATOM): + self.ALMPER.append(eval(Pop(Item_list,0))) + + self.IAPER = [] + for i in range(self.NATOM): + self.IAPER.append(eval(Pop(Item_list,0))) + + self.IACPER = [] + for i in range(self.NATOM): + self.IACPER.append(eval(Pop(Item_list,0))) + + self.CGPER = [] + for i in range(self.NATOM): + self.CGPER.append(eval(Pop(Item_list,0))) + + #.................................................... + + self.IPOL = 0 + if self.IPOL == 1: + if len(Item_list) < self.NATOM: + print '(error: File too short!)' + return -1 + print 'Reading Polarizability Data. For details, refer to online AMBER format manual' + self.ATPOL = [] + for i in range(self.NATOM): + self.ATPOL.append(eval(Pop(Item_list,0))) + + if self.IFPERT == 1: + if len(Item_list) < self.NATOM: + print '(error: File too short!)' + return -1 + self.ATPOL1 = [] + for i in range(self.NATOM): + self.ATPOL1.append(eval(Pop(Item_list,0))) + + #.................................................... + + if len(Item_list): + print '(warning: File too large!)', + + print 'done.' + self.TOP_is_read = 1 + +#============================================================ + +def Find_Amber_files(): + 'Look for sets of Amber files to process' + '''If not passed anything on the command line, look for pairs of + Amber files (.crd and .top) in the current directory. For + each set if there is no corresponding Lammps file (data.), or it is + older than any of the Amber files, add its basename to a list of + strings. This list is returned by the function''' + + # Date and existence checks not yet implemented + + import os, sys + + Basename_list = [] + + # Extract basenames from command line + for Name in sys.argv[1:]: + if Name[-4:] == '.crd': + Basename_list.append(Name[:-4]) + else: + if Name[-4:] == '.top': + Basename_list.append(Name[:-4]) + else: + Basename_list.append(Name) + + # Remove duplicate basenames + for Basename in Basename_list[:]: + while Basename_list.count(Basename) > 1: + Basename_list.remove(Basename) + + if Basename_list == []: + print 'Looking for Amber files...', + Dir_list = os.listdir('.') + Dir_list.sort() + for File in Dir_list: + if File[-4:] == '.top': + Basename = File[:-4] + if (Basename + '.crd') in Dir_list: + Basename_list.append(Basename) + if Basename_list != []: + print 'found', + for i in range(len(Basename_list)-1): + print Basename_list[i] + ',', + print Basename_list[-1] + '\n' + + if Basename_list == []: + print 'none.\n' + + return Basename_list + +#============================================================ + +def Convert_Amber_files(): + 'Handle the whole conversion process' + print + print 'Welcome to amber2lammps, a program to convert Amber files to Lammps format!' + print + Basename_list = Find_Amber_files() + for Basename in Basename_list: + a = Amber() + a.Read_CRD(Basename) + if a.CRD_is_read: + a.Read_TOP(Basename) + if a.TOP_is_read: + l = a.Coerce_to_Lammps() + l.Write_Lammps(Basename) + del l + del a + print + +#============================================================ + +Convert_Amber_files()