Ignore:
Timestamp:
Dec 10, 2012, 10:10:59 AM (13 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, Candidate_v1.7.0, Candidate_v1.7.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.
File:
1 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}
Note: See TracChangeset for help on using the changeset viewer.