The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

HackaMol::PhysVecMVRRole - Provides the core of HackaMol Atom and Molecule classes.

VERSION

version 0.00_07

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) 2013 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.