Changeset a82602


Ignore:
Timestamp:
Dec 10, 2012, 10:10:59 AM (12 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
82cbe4
Parents:
5a5196
git-author:
Frederik Heber <heber@…> (09/12/12 15:23:13)
git-committer:
Frederik Heber <heber@…> (12/10/12 10:10:59)
Message:

InterfaceVMGJob now also calculates nuclei interaction energy.

  • necessiated to Particle::commMPI().
  • CommParticles() call in ImportRightHandSide().
  • in ExportSolution() we just copied stuff from interface_particles.cpp from VMG project.
  • returndata.e_long now contains calculated energy from there.
Location:
src/Jobs
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Jobs/InterfaceVMGJob.cpp

    r5a5196 ra82602  
    4141#include "grid/grid.hpp"
    4242#include "grid/multigrid.hpp"
     43#include "units/particle/comm_mpi_particle.hpp"
     44#include "units/particle/interpolation.hpp"
     45#include "units/particle/linked_cell_list.hpp"
    4346#include "mg.hpp"
    4447
     
    98101
    99102  Grid& grid = multigrid(multigrid.MaxLevel());
     103  grid.Clear();
    100104  //grid.ClearBoundary(); // we don't have a boundary under periodic boundary conditions
    101105
     
    114118   * Charge assignment on the grid
    115119   */
    116   Comm& comm = *MG::GetComm();
     120  Particle::CommMPI& comm = *dynamic_cast<Particle::CommMPI*>(MG::GetComm());
    117121  Grid& particle_grid = comm.GetParticleGrid();
    118 
    119122  particle_grid.Clear();
     123
     124  // distribute particles
     125  particles.clear();
     126  comm.CommParticles(grid, particles);
    120127
    121128  assert(particle_grid.Global().LocalSize().IsComponentwiseGreater(
     
    180187void InterfaceVMGJob::ExportSolution(Grid& grid)
    181188{
     189  /// sample the obtained potential to evaluate with the electron charge density
     190
    182191  // grid now contains the sough-for potential
    183   Comm& comm = *MG::GetComm();
     192  //Comm& comm = *MG::GetComm();
     193  Particle::CommMPI& comm = *dynamic_cast<Particle::CommMPI*>(MG::GetComm());
    184194
    185195  const Index begin_local = grid.Global().LocalBegin() - grid.Local().HaloSize1();
     
    207217  comm.PrintStringOnce("Grid potential sum: %e", potential_sum);
    208218
    209   //Particle::CommMPI& comm = *dynamic_cast<Particle::CommMPI*>(MG::GetComm());
    210   returndata.e_long = potential_sum;
     219  {
     220    Grid::iterator grid_iter = grid.Iterators().Local().Begin();
     221    comm.PrintStringOnce("Grid potential at (0,0,0): %e", grid.GetVal(*grid_iter));
     222  }
     223
     224  //Particle::CommMPI& comm = *dynamic_cast<Particle::CommMPI*>(MG::GetComm());  returndata.e_long = potential_sum;
     225
     226  /// Calculate potential energy of nuclei
     227
     228  vmg_float e = 0.0;
     229  vmg_float e_long = 0.0;
     230  vmg_float e_self = 0.0;
     231  vmg_float e_short_peak = 0.0;
     232  vmg_float e_short_spline = 0.0;
     233
     234  Factory& factory = MG::GetFactory();
     235
     236  /*
     237   * Get parameters and arrays
     238   */
     239  const vmg_int& near_field_cells = factory.GetObjectStorageVal<int>("PARTICLE_NEAR_FIELD_CELLS");
     240  const vmg_int& interpolation_degree = factory.GetObjectStorageVal<int>("PARTICLE_INTERPOLATION_DEGREE");
     241
     242  Particle::Interpolation ip(interpolation_degree);
     243
     244  const vmg_float r_cut = near_field_cells * grid.Extent().MeshWidth().Max();
     245
     246  /*
     247   * Copy potential values to a grid with sufficiently large halo size.
     248   * This may be optimized in future.
     249   * The parameters of this grid have been set in the import step.
     250   */
     251  Grid& particle_grid = comm.GetParticleGrid();
     252
     253  for (i.X()=0; i.X()<grid.Local().Size().X(); ++i.X())
     254    for (i.Y()=0; i.Y()<grid.Local().Size().Y(); ++i.Y())
     255      for (i.Z()=0; i.Z()<grid.Local().Size().Z(); ++i.Z())
     256        particle_grid(i + particle_grid.Local().Begin()) = grid.GetVal(i + grid.Local().Begin());
     257
     258  comm.CommToGhosts(particle_grid);
     259
     260  /*
     261   * Compute potentials
     262   */
     263  Particle::LinkedCellList lc(particles, near_field_cells, grid);
     264  Particle::LinkedCellList::iterator p1, p2;
     265  Grid::iterator iter;
     266
     267  comm.CommLCListToGhosts(lc);
     268
     269  for (int i=lc.Local().Begin().X(); i<lc.Local().End().X(); ++i)
     270    for (int j=lc.Local().Begin().Y(); j<lc.Local().End().Y(); ++j)
     271      for (int k=lc.Local().Begin().Z(); k<lc.Local().End().Z(); ++k) {
     272
     273  if (lc(i,j,k).size() > 0)
     274    ip.ComputeCoefficients(particle_grid, Index(i,j,k) - lc.Local().Begin() + particle_grid.Local().Begin());
     275
     276  for (p1=lc(i,j,k).begin(); p1!=lc(i,j,k).end(); ++p1) {
     277
     278    // Interpolate long-range part of potential and electric field
     279    ip.Evaluate(**p1);
     280
     281    // Subtract self-induced potential
     282    (*p1)->Pot() -= (*p1)->Charge() * spl.GetAntiDerivativeAtZero();
     283
     284    e_long += 0.5 * (*p1)->Charge() * ip.EvaluatePotentialLR(**p1);
     285    e_self += 0.5 * (*p1)->Charge() * (*p1)->Charge() * spl.GetAntiDerivativeAtZero();
     286
     287    for (int dx=-1*near_field_cells; dx<=near_field_cells; ++dx)
     288      for (int dy=-1*near_field_cells; dy<=near_field_cells; ++dy)
     289        for (int dz=-1*near_field_cells; dz<=near_field_cells; ++dz) {
     290
     291    for (p2=lc(i+dx,j+dy,k+dz).begin(); p2!=lc(i+dx,j+dy,k+dz).end(); ++p2)
     292
     293      if (*p1 != *p2) {
     294
     295        const Vector dir = (*p1)->Pos() - (*p2)->Pos();
     296        const vmg_float length = dir.Length();
     297
     298        if (length < r_cut) {
     299
     300          (*p1)->Pot() += (*p2)->Charge() / length * (1.0 + spl.EvaluatePotential(length));
     301          (*p1)->Field() += (*p2)->Charge() * dir * spl.EvaluateField(length);
     302
     303          e_short_peak += 0.5 * (*p1)->Charge() * (*p2)->Charge() / length;
     304          e_short_spline += 0.5 * (*p1)->Charge() * (*p2)->Charge() / length * spl.EvaluatePotential(length);
     305        }
     306      }
     307        }
     308  }
     309      }
     310
     311  /* Remove average force term */
     312  Vector average_force = 0.0;
     313  for (std::list<Particle::Particle>::const_iterator iter=particles.begin(); iter!=particles.end(); ++iter)
     314    average_force += iter->Charge() * iter->Field();
     315  const vmg_int& npl = MG::GetFactory().GetObjectStorageVal<vmg_int>("PARTICLE_NUM_LOCAL");
     316  const vmg_int num_particles_global = comm.GlobalSum(npl);
     317  average_force /= num_particles_global;
     318  comm.GlobalSumArray(average_force.vec(), 3);
     319  for (std::list<Particle::Particle>::iterator iter=particles.begin(); iter!=particles.end(); ++iter)
     320    iter->Field() -= average_force / iter->Charge();
     321
     322  comm.CommParticlesBack(particles);
     323
     324  vmg_float* q = factory.GetObjectStorageArray<vmg_float>("PARTICLE_CHARGE_ARRAY");
     325  const vmg_int& num_particles_local = factory.GetObjectStorageVal<vmg_int>("PARTICLE_NUM_LOCAL");
     326  const vmg_float* p = factory.GetObjectStorageArray<vmg_float>("PARTICLE_POTENTIAL_ARRAY");
     327//  const vmg_float* f = factory.GetObjectStorageArray<vmg_float>("PARTICLE_FIELD_ARRAY");
     328
     329
     330  e_long = comm.GlobalSumRoot(e_long);
     331  e_short_peak = comm.GlobalSumRoot(e_short_peak);
     332  e_short_spline = comm.GlobalSumRoot(e_short_spline);
     333  e_self = comm.GlobalSumRoot(e_self);
     334
     335  for (int j=0; j<num_particles_local; ++j)
     336    e += 0.5 * p[j] * q[j];
     337  e = comm.GlobalSumRoot(e);
     338
     339  comm.PrintStringOnce("E_long:         %e", e_long);
     340  comm.PrintStringOnce("E_short_peak:   %e", e_short_peak);
     341  comm.PrintStringOnce("E_short_spline: %e", e_short_spline);
     342  comm.PrintStringOnce("E_self:         %e", e_self);
     343  comm.PrintStringOnce("E_total:        %e", e);
     344  comm.PrintStringOnce("E_total*:       %e", e_long + e_short_peak + e_short_spline - e_self);
     345
     346  returndata.e_long = e;
    211347}
  • src/Jobs/VMGJob.cpp

    r5a5196 ra82602  
    6363//#include "solver/solver_regular.hpp"
    6464#include "solver/solver_singular.hpp"
    65 //#include "units/particle/comm_mpi_particle.hpp"
     65#include "units/particle/comm_mpi_particle.hpp"
    6666
    6767#include "CodePatterns/MemDebug.hpp"
     
    7171#include "LinearAlgebra/defs.hpp"
    7272#include "Jobs/InterfaceVMGJob.hpp"
     73
     74#include "CodePatterns/Assert.hpp"
    7375
    7476using namespace VMG;
     
    8587  particle_charges(_particle_charges),
    8688  near_field_cells(_near_field_cells),
    87   returndata(static_cast<const SamplingGridProperties &>(_density_grid))
     89  returndata(static_cast<const SamplingGridProperties &>(_density_grid)),
     90  num_particles(0),
     91  f(NULL),
     92  x(NULL),
     93  p(NULL),
     94  q(NULL)
    8895{}
    8996
    9097VMGJob::VMGJob() :
    9198  FragmentJob(JobId::IllegalJob),
    92   near_field_cells(5)
     99  near_field_cells(5),
     100  num_particles(0),
     101  f(NULL),
     102  x(NULL),
     103  p(NULL),
     104  q(NULL)
    93105{}
    94106
    95107VMGJob::~VMGJob()
    96 {}
     108{
     109  delete[] f;
     110  delete[] x;
     111  delete[] p;
     112  delete[] q;
     113}
     114
     115void VMGJob::InitVMGArrays()
     116{
     117  num_particles = particle_charges.size();
     118  f = new double[num_particles*3];
     119  x = new double[num_particles*3];
     120  p = new double[num_particles];
     121  q = new double[num_particles];
     122
     123  {
     124    size_t index=0;
     125    for (std::vector< std::vector< double > >::const_iterator iter = particle_positions.begin();
     126        iter != particle_positions.end(); ++iter) {
     127      for (std::vector< double >::const_iterator positer = (*iter).begin();
     128          positer != (*iter).end(); ++positer) {
     129        f[index] = 0.;
     130        x[index++] = *positer;
     131      }
     132    }
     133    ASSERT( index == num_particles*3,
     134        "VMGJob::VMGJob() - too many particles or components in particle_positions.");
     135  }
     136  {
     137    size_t index = 0;
     138    for (std::vector< double >::const_iterator iter = particle_charges.begin();
     139        iter != particle_charges.end(); ++iter) {
     140      p[index] = 0.;
     141      q[index++] = *iter;
     142    }
     143    ASSERT( index == num_particles,
     144        "VMGJob::VMGJob() - too many charges in particle_charges.");
     145  }
     146}
     147
    97148
    98149FragmentResult::ptr VMGJob::Work()
     
    137188   */
    138189#ifdef HAVE_MPI
    139   new CommMPI(boundary, new DomainDecompositionMPI());
     190  new Particle::CommMPI(boundary, new DomainDecompositionMPI());
    140191#else
    141192  new CommSerial(boundary);
     
    169220  new ObjectStorage<int>("PARTICLE_INTERPOLATION_DEGREE", 3);
    170221
     222  // first initialize f,x,p,q,... from STL vectors
     223  InitVMGArrays();
     224  // then initialize as objects with VMG's storage
     225  new ObjectStorage<vmg_float*>("PARTICLE_POS_ARRAY", x);
     226  new ObjectStorage<vmg_float*>("PARTICLE_CHARGE_ARRAY", q);
     227  new ObjectStorage<vmg_float*>("PARTICLE_POTENTIAL_ARRAY", p);
     228  new ObjectStorage<vmg_float*>("PARTICLE_FIELD_ARRAY", f);
     229  new ObjectStorage<vmg_int>("PARTICLE_NUM_LOCAL", num_particles);
     230
    171231  /*
    172232   * Post init
  • src/Jobs/VMGJob.hpp

    r5a5196 ra82602  
    5353  void InitVMG();
    5454
     55  void InitVMGArrays();
     56
    5557private:
    5658  //!> sampled density required as input
     
    6668  //!> temporary instance to hold return data
    6769  VMGData returndata;
     70
     71  //!> number of particles
     72  size_t num_particles;
     73  //!> forces array
     74  double *f;
     75  //!> position array
     76  double *x;
     77  //!> potential array
     78  double *p;
     79  //!> charge array
     80  double *q;
    6881
    6982private:
Note: See TracChangeset for help on using the changeset viewer.