Changeset fa2c89


Ignore:
Timestamp:
Mar 24, 2017, 10:12:25 AM (8 years ago)
Author:
Frederik Heber <heber@…>
Branches:
FitPartialCharges_GlobalError
Children:
9afdef
Parents:
e6a2ef
git-author:
Frederik Heber <heber@…> (10/10/16 12:35:24)
git-committer:
Frederik Heber <heber@…> (03/24/17 10:12:25)
Message:

Added calculation of l2 error of fitted charges against each full_potential level.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/PotentialAction/FitFragmentPartialChargesAction.cpp

    re6a2ef rfa2c89  
    330330}
    331331
     332static bool getFullPositions(
     333    PartialNucleiChargeFitter::positions_t &positions,
     334    PartialNucleiChargeFitter::charges_t &charges)
     335{
     336  /// \note we cannot use the summed up Fragment here, as the saturation hydrogens
     337  /// are in the way and cannot be sorted out properly/in a simple fashion.
     338  const World &world = const_cast<const World &>(World::getInstance());
     339  const ParticleRegistry &registry = const_cast<const ParticleRegistry &>(ParticleRegistry::getInstance());
     340  {
     341    const World::ConstAtomComposite &atoms = world.getAllAtoms();
     342    positions.reserve(atoms.size());
     343    charges.reserve(atoms.size());
     344    for (World::ConstAtomComposite::const_iterator iter = atoms.begin();
     345        iter != atoms.end(); ++iter) {
     346      // set position for this atom
     347      const Vector &pos = (*iter)->getPosition();
     348
     349      // use the fitted charges
     350      const atomId_t atomid = (*iter)->getId();
     351      std::string particlename = (*iter)->getParticleName();
     352      if (particlename.empty())
     353        particlename = (*iter)->getElement().getSymbol();
     354      if (registry.isPresentByName(particlename)) {
     355        const Particle * const particle = registry.getByName(particlename);
     356        LOG(3, "DEBUG: Using implicit charge " << particle->charge << " of particle "
     357            << particle->getName() << " for atom " << atomid);
     358        positions.push_back((1./AtomicLengthToAngstroem)*pos);
     359        charges.push_back(particle->charge);
     360      } else {
     361        ELOG(1, "Could not find fitted charge for " << particlename);
     362        return false;
     363      }
     364    }
     365  }
     366  return true;
     367}
     368
     369
    332370static bool isNotHydrogen(const atom * const _atom)
    333371{
     
    588626  }
    589627
     628  // compute the global error using the full solutions
     629  {
     630    FragmentationResultContainer::longrangedata_t longrangeData = resultscontainer.getLongRangeResults();
     631    FragmentationResultContainer::longrangedata_t::iterator iter = longrangeData.end();
     632    const size_t MaxLevel = std::max_element(fragments.begin(), fragments.end(), keyset_comparator)->size();
     633    std::advance(iter, -MaxLevel);
     634    FragmentationResultContainer::longrangedata_t::iterator remove_iter = iter;
     635    std::vector<VMGData> fullsolutionData;
     636    for (; iter != longrangeData.end(); ++iter)
     637      fullsolutionData.push_back(iter->second);
     638    if (longrangeData.size() > 1) // when there's just a single fragment, it corresponds to full solution
     639      longrangeData.erase(remove_iter, longrangeData.end());
     640
     641    // extraction of all positions is not easy as we cannot use the summed up
     642    // fragments due to saturated hydrogens. Also, we cannot easily removed the
     643    // non-selected atoms from the set. Hence, the error is always calculated
     644    // against all atoms.
     645    PartialNucleiChargeFitter::positions_t fullpositions;
     646    PartialNucleiChargeFitter::charges_t fullcharges;
     647    getFullPositions(fullpositions, fullcharges);
     648    PartialNucleiChargeFitter::charges_t zerocharges(fullpositions.size(), 0.);
     649    LOG(4, "DEBUG: Full positions are " << fullpositions);
     650    LOG(4, "DEBUG: Full (fitted) charges are " << fullcharges);
     651
     652    for (size_t i=0;i<fullsolutionData.size();++i) {
     653      // get positions and potential
     654      const SamplingGrid &fullpotential = fullsolutionData[i].both_sampled_potential;
     655      if ((fullpotential.level == 0)
     656          || ((fullpotential.begin[0] == fullpotential.end[0])
     657              && (fullpotential.begin[1] == fullpotential.end[1])
     658              && (fullpotential.begin[2] == fullpotential.end[2]))) {
     659        ELOG(1, "Sampled grid contains grid made of zero points.");
     660        return Action::failure;
     661      }
     662
     663      // set up matrix and calculate residual
     664      PartialNucleiChargeFitter fitter(fullpotential, fullpositions, params.radius.get());
     665      if (!fitter.setCharges(zerocharges)) {
     666        ELOG(1, "fullcharges and fullpositions do not coincide in size, internal error.");
     667        return Action::failure;
     668      }
     669      VectorContent potential_norm = fitter.calculateResiduum();
     670      if (!fitter.setCharges(fullcharges)) {
     671        ELOG(1, "fullcharges and fullpositions do not coincide in size, internal error.");
     672        return Action::failure;
     673      }
     674      VectorContent residuum = fitter.calculateResiduum();
     675
     676      LOG(1, "INFO: At order " << i+1 << " we have an error of " << residuum.Norm()
     677          << " against the potential norm of " << potential_norm.Norm());
     678    }
     679  }
     680
    590681  return Action::success;
    591682#else
Note: See TracChangeset for help on using the changeset viewer.