NAME
HackaMol::PhysVecMVRRole - Provides the core of HackaMol Atom and Molecule classes.
VERSION
version 0.015
SYNOPSIS
# instance of class that consumes the PhysVecRol
use HackaMol::Molecule;
my $obj = HackaMol::Molecule->new(
name => 'foo',
t => 0 ,
charges => [0.1],
coords => [ V(0,1,2) ]
);
# add some charges
$obj->push_charges($_) foreach ( 0.3, 0.2, 0.1, -0.1, -0.2, -0.36 );
my $sum_charges = 0;
$sum_charges += $_ foreach $obj->all_charges;
print "average charge: ", $sum_charges / $obj->count_charges;
# add some coordinates
$obj->push_coords($_) foreach ( V(0,0,0), V(1,1,1), V(-1.0,2.0,-4.0) ) );
print $obj->mean_charges . "\n";
print $obj->msd_charges . "\n";
printf ("%10.3f %10.3f %10.3f \n", @{$obj->mean_coords};
print $obj->msd_coords . "\n";
DESCRIPTION
PhysVecMVR provides the core attributes and methods shared between Atom and Molecule classes. Consuming this role gives Classes a place to store coordinates, forces, and charges, perhaps, over the course of a simulation or for a collection of configurations for which all other object metadata (name, mass, etc) remains fixed. As such, the 't' attribute, described below, is important to understand. The PhysVecMVR uses Math::Vector::Real (referred to as MVR), which has pure Perl and XS implementations. MVR::XS is fast with many useful/powerful overloaded methods. PhysVecMVR leaves many attributes rw so that they may be set and reset on the fly. This seems most intuitive from the perspective of carrying out computational work on molecules.
Comparing the PhysVec within Atom and Molecule may be helpful. For both, the PhysVecRol generates a little metadata (mass, name, etc.) and an array of coordinates, forces, and charges. For an atom, the array of coordinates gives an atom (with fixed metadata) the ability to store multiple [x,y,z] positions (as a function of time, symmetry, distribution, etc.). What is the array of coordinates for Molecule? Usually, the coordinates for a molecule will likely remain empty (because the atoms that Molecule contains have the more useful coordinates), but we can imagine using the coordinates array to track the center of mass of the molecule if needed.
In the following: Methods with mean_foo msd_foo intra_dfoo out front, carries out some analysis within $self. Methods with inter_ out front carries out some analysis between two objects of classes that consume PhysVecMVR at the $self->t and $obj->t.
METHODS
distance
Takes one argument ($obj2) and calculates the distance using Math::Vector::Real
$obj1->distance($obj2);
angle_deg
Takes two arguments ($obj2,$obj3) and calculates the angle (degrees) between the vectors with $obj1 as orgin using Math::Vector::Real.
$obj1->angle_deg($obj2,$obj3);
angle_rad
Takes two arguments ($obj2,$obj3) and calculates the angle (radians) between the vectors with $obj1 as orgin using Math::Vector::Real.
$obj1->angle_rad($obj2,$obj3);
dihedral_deg
Takes three arguments ($obj2,$obj3,obj4) and calculates the angle (degrees) between the vectors normal to the planes containing the first three and last three objects using Math::Vector::Real.
$obj1->dihedral_deg($obj2,$obj3,$obj4);
dihedral_rad
Takes three arguments ($obj2,$obj3,obj4) and calculates the angle (radians) between the vectors normal to the planes containing the first three and last three objects using Math::Vector::Real.
$obj1->dihedral_rad($obj2,$obj3,$obj4);
intra_dcharges
Calculates the change in charge from initial t ($ti) to final t ($tf). I.e.:
$obj1->intra_dcharges( $ti, $tf );
yields the same as:
$self->get_charges($tf) - $self->get_charges($ti);
mean_charges
No arguments. Calculates the mean of all stored charges.
msd_charges
No arguments. Calculates the mean square deviation of all stored charges.
intra_dcoords intra_dforces
returns the difference (Math::Vector::Real object) from the initial t ($ti) to the final t ($tf).
$obj1->intra_dcoords($ti,$tf);
$obj1->intra_dforces($ti,$tf);
mean_coords mean_forces
No arguments. Calculates the mean (Math::Vector::Real object) vector.
msd_coords msd_forces
No arguments. Calculates the mean (Math::Vector::Real object) dot product of the vector difference of the xyz coords from the mean vector.
charge
called with no arguments. returns $self->get_charges($self->t);
xyz
called with no arguments. returns $self->get_coords($self->t);
clone_xyz
optionally called with t. t set to $self->t if not passed. This method is intended for mapping from one atom to another, where the coordinates are expected to be distinct. A copy of the xyz coordinates with a new memory location is returned via V( @{$self->get_coords($t)});
my @Aus = map {
HackaMol::Atom->new(Z=>79, coords=>[$_->clone_xyz])
} grep {$_->Z == 80} @atoms;
force
called with no arguments. returns $self->get_forces($self->t);
clone_force
optionally called with t. t set to $self->t if not passed. Analagous to clone_xyz.
copy_ref_from_t1_through_t2
called as $obj->copy_ref_from_t1_through_t2($qcf,$t,$tf); where qcf is charges|coords|forces. Fills the qcf from t+1 to tf with the value at t. Added this while trying to compare a dipole as a function of changing charges at a single set of coordinates.
ARRAY METHODS
push_$_, all_$_, get_$_, set_$_, count_$_, clear_$_ foreach qw(charges coords forces)
ARRAY traits, respectively: push, get, set, all, elements, delete, clear Descriptions for charges and coords follows. forces analogous to coords.
push_charges
push value on to charges array
$obj->push_charges($_) foreach (0.15, 0.17, 0.14, 0.13);
all_charges
returns array of all elements in charges array
print $_ . " " foreach $obj->all_charges; # prints 0.15 0.17 0.14 0.13
get_charges
return element by index from charges array
print $obj->get_charges(1); # prints 0.17
set_charges
set value of element by index from charges array
$obj->set_charges(2, 1.00);
print $_ . " " foreach $obj->all_charges; # prints 0.15 0.17 1.00 0.13
count_charges
return number of elements in charges array
print $obj->count_charges; # prints 4
delete_charges($index)
Removes the element at the given index from the array.
This method returns the deleted value. Note that if no value exists, it will return undef.
This method requires one argument.
clear_charges
clears charges array
$obj->clear_charges;
print $_ . " " foreach $obj->all_charges; # does nothing
print $obj->count_charges; # prints 0
push_coords
push value on to coords array
$obj->push_coords($_) foreach ([0,0,0],[1,1,1],[-1.0,2.0,-4.0], [3,3,3]);
all_coords
returns array of all elements in coords array
printf ("%10.3f %10.3f %10.3f \n", @{$_}) foreach $obj->all_coords;
my @new_coords = map {[$_->[0]+1,$_->[1]+1,$_->[2]+1]} $obj->all_coords;
printf ("%10.3f %10.3f %10.3f \n", @{$_}) foreach @new_coords;
get_coords
return element by index from coords array
printf ("%10.3f %10.3f %10.3f \n", @{$obj->get_coords(1)}); #
set_coords
set value of element by index from coords array
$obj->set_coords(2, [100,100,100]);
printf ("%10.3f %10.3f %10.3f \n", @{$_}) foreach $obj->all_coords;
count_coords
return number of elements in coords array
print $obj->count_coords; # prints 4
delete_coords($index)
Removes the element at the given index from the array.
This method returns the deleted value. Note that if no value exists, it will return undef.
This method requires one argument.
clears coords array
$obj->clear_coords;
print $_ . " " foreach $obj->all_coords; # does nothing
print $obj->count_coords # prints 0
clear_coords
clears coords array
$obj->clear_coords;
print $_ . " " foreach $obj->all_coords; # does nothing
print $obj->count_coords # prints 0
ATTRIBUTES
t
isa Int or ScalarRef that is rw with default of 0
t is intended to describe the current "setting" of the object. Objects that consume the PhysVecRol have arrays of coordinates, forces, and charges to allow storage with the passing of time (hence t) or the generation alternative configurations. For example, a crystal lattice can be stored as a single object that consumes PhysVec (with associated metadata) along with the array of 3d-coordinates resulting from lattice vector translations.
Experimental: Setting t to a ScalarRef allows all objects to share the same t. Although, to use this, a $self->t accessor that dereferences the value would seem to be required. There is nothing, currently, in the core to do so. Not sure yet if it is a good or bad idea to do so.
my $t = 0;
my $rt = \$t;
$_->t($rt) for (@objects);
$t = 1; # change t for all objects.
mass
isa Num that is rw and lazy with a default of 0
xyzfree
isa ArrayRef that is rw and lazy with a default value [1,1,1]. Using this array allows the object to be fixed for calculations that support it. For example, to fix the X and Y coordinates:
$obj->xyzfree([0,0,1]);
fixing any coordinate will set trigger the is_fixed(1) flag.
is_fixed
isa Bool that is rw and lazy with a default of 0 (false).
charges
isa ArrayRef[Num] that is lazy with public ARRAY traits described in ARRAY_METHODS
Gives atoms and molecules t-dependent arrays of charges. e.g. store and analyze atomic charges from a quantum mechanical molecule in several intramolecular configurations or a fixed configuration in varied external potentials.
coords forces
isa ArrayRef[Math::Vector::Real] that is lazy with public ARRAY traits described in ARRAY_METHODS
Gives atoms and molecules t-dependent arrays of coordinates and forces, for the purpose of analysis.
SEE ALSO
AUTHOR
Demian Riccardi <demianriccardi@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2015 by Demian Riccardi.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.