Changeset c1ec8e for src/Actions
- Timestamp:
- May 18, 2016, 10:02:53 PM (9 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, 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_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, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, 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:
- 91f907
- Parents:
- 01120c
- git-author:
- Frederik Heber <heber@…> (03/07/16 21:03:37)
- git-committer:
- Frederik Heber <heber@…> (05/18/16 22:02:53)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/PotentialAction/FitPartialChargesAction.cpp
r01120c rc1ec8e 171 171 } 172 172 173 ActionState::ptr PotentialFitPartialChargesAction::performCall() 174 { 175 // check for selected atoms 176 const World &world = const_cast<const World &>(World::getInstance()); 177 if (world.beginAtomSelection() == world.endAtomSelection()) { 178 STATUS("There are no atoms selected for fitting partial charges to."); 179 return Action::failure; 180 } 181 182 /// obtain possible fragments to each selected atom 183 const AtomFragmentsMap &atomfragments = AtomFragmentsMap::getConstInstance(); 184 if (!atomfragments.checkCompleteness()) { 185 STATUS("AtomFragmentsMap failed internal consistency check, missing forcekeysets?"); 186 return Action::failure; 187 } 173 static 174 std::set<KeySet> accumulateKeySetsForAtoms( 175 const AtomFragmentsMap::AtomFragmentsMap_t &_atommap, 176 const std::vector<const atom *> &_selected_atoms) 177 { 188 178 std::set<KeySet> fragments; 189 const AtomFragmentsMap::AtomFragmentsMap_t &atommap = atomfragments.getMap();190 for (World::AtomSelectionConstIterator iter = world.beginAtomSelection();191 iter != world.endAtomSelection(); ++iter) {179 for (std::vector<const atom *>::const_iterator iter = _selected_atoms.begin(); 180 iter != _selected_atoms.end(); ++iter) { 181 const atomId_t atomid = (*iter)->getId(); 192 182 const AtomFragmentsMap::AtomFragmentsMap_t::const_iterator atomiter = 193 atommap.find(iter->first);194 if ( iter->second->getElementNo() != 1) {195 if (atomiter == atommap.end()) {196 ELOG(2, "There are no fragments associated to " << iter->first<< ".");183 _atommap.find(atomid); 184 if ((*iter)->getElementNo() != 1) { 185 if (atomiter == _atommap.end()) { 186 ELOG(2, "There are no fragments associated to " << atomid << "."); 197 187 continue; 198 188 } 199 189 const AtomFragmentsMap::keysets_t &keysets = atomiter->second; 200 LOG(2, "DEBUG: atom " << iter->first<< " has " << keysets.size() << " fragments.");190 LOG(2, "DEBUG: atom " << atomid << " has " << keysets.size() << " fragments."); 201 191 fragments.insert( keysets.begin(), keysets.end() ); 202 192 } else { 203 LOG(3, "DEBUG: Skipping atom " << iter->first << " as it's hydrogen."); 204 } 205 } 206 207 // reduce given fragments to homologous graphs to avoid multiple fittings 208 typedef std::map<KeySet, HomologyGraph> KeysetsToGraph_t; 209 KeysetsToGraph_t keyset_graphs; 210 typedef std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> GraphFittedChargeMap_t; 211 GraphFittedChargeMap_t fittedcharges_per_fragment; 212 HomologyContainer &homologies = World::getInstance().getHomologies(); 213 for (std::set<KeySet>::const_iterator fragmentiter = fragments.begin(); 214 fragmentiter != fragments.end(); ++fragmentiter) { 193 LOG(3, "DEBUG: Skipping atom " << atomid << " as it's hydrogen."); 194 } 195 } 196 return fragments; 197 } 198 199 static 200 void getKeySetsToGraphMapping( 201 std::map<KeySet, HomologyGraph> &_keyset_graphs, 202 std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> &_fittedcharges_per_fragment, 203 const std::set<KeySet> &_fragments, 204 const AtomFragmentsMap &_atomfragments) 205 { 206 for (std::set<KeySet>::const_iterator fragmentiter = _fragments.begin(); 207 fragmentiter != _fragments.end(); ++fragmentiter) { 215 208 const KeySet &keyset = *fragmentiter; 216 const AtomFragmentsMap::indices_t &forceindices = atomfragments.getFullKeyset(keyset);209 const AtomFragmentsMap::indices_t &forceindices = _atomfragments.getFullKeyset(keyset); 217 210 ASSERT( !forceindices.empty(), 218 "PotentialFitPartialChargesAction::performCall() - force keyset to " 219 +toString(keyset)+" is empty."); 211 "getKeySetsToGraphMapping() - force keyset to "+toString(keyset)+" is empty."); 220 212 KeySet forcekeyset; 221 213 forcekeyset.insert(forceindices.begin(), forceindices.end()); … … 223 215 const HomologyGraph graph(forcekeyset); 224 216 LOG(2, "DEBUG: Associating keyset " << forcekeyset << " with graph " << graph); 225 keyset_graphs.insert( std::make_pair(keyset, graph) ); 226 fittedcharges_per_fragment.insert( std::make_pair(graph, PartialNucleiChargeFitter::charges_t()) ); 227 } 228 229 /// then go through all fragments and get partial charges for each 230 for (GraphFittedChargeMap_t::iterator graphiter = fittedcharges_per_fragment.begin(); 231 graphiter != fittedcharges_per_fragment.end(); ++graphiter) { 217 _keyset_graphs.insert( std::make_pair(keyset, graph) ); 218 _fittedcharges_per_fragment.insert( std::make_pair(graph, PartialNucleiChargeFitter::charges_t()) ); 219 } 220 } 221 222 static 223 bool getPartialChargesForAllGraphs( 224 std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> &_fittedcharges_per_fragment, 225 const HomologyContainer &_homologies, 226 const double _mask_radius, 227 const bool enforceZeroCharge) 228 { 229 typedef std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> GraphFittedChargeMap_t; 230 for (GraphFittedChargeMap_t::iterator graphiter = _fittedcharges_per_fragment.begin(); 231 graphiter != _fittedcharges_per_fragment.end(); ++graphiter) { 232 232 const HomologyGraph &graph = graphiter->first; 233 233 LOG(2, "DEBUG: Now fitting charges to graph " << graph); 234 const HomologyContainer::range_t range = homologies.getHomologousGraphs(graph);234 const HomologyContainer::range_t range = _homologies.getHomologousGraphs(graph); 235 235 if (range.first == range.second) { 236 STATUS("HomologyContainer does not contain specified fragment.");237 return Action::failure;236 ELOG(0, "HomologyContainer does not contain specified fragment."); 237 return false; 238 238 } 239 239 … … 241 241 PartialNucleiChargeFitter::charges_t &averaged_charges = graphiter->second; 242 242 const size_t NoFragments = 243 obtainAverageChargesOverFragments(averaged_charges, range, params.radius.get());243 obtainAverageChargesOverFragments(averaged_charges, range, _mask_radius); 244 244 if ((NoFragments == 0) && (range.first != range.second)) { 245 STATUS("Fitting for fragment "+toString(*graphiter)+" failed.");246 return Action::failure;245 ELOG(0, "Fitting for fragment "+toString(*graphiter)+" failed."); 246 return false; 247 247 } 248 248 249 249 // make sum of charges zero if desired 250 if ( params.enforceZeroCharge.get())250 if (enforceZeroCharge) 251 251 enforceZeroTotalCharge(averaged_charges); 252 252 … … 255 255 << averaged_charges << ", averaged over " << NoFragments << " fragments."); 256 256 } 257 258 /// obtain average charge for each atom the fitted charges over all its fragments 257 return true; 258 } 259 260 double fitAverageChargeToAtom( 261 const atom * const _walker, 262 const AtomFragmentsMap &_atomfragments, 263 const std::map<KeySet, HomologyGraph> &_keyset_graphs, 264 const std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> &_fittedcharges_per_fragment) 265 { 266 typedef std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> GraphFittedChargeMap_t; 267 const atom * surrogate = _walker; 268 if (surrogate->getElementNo() == 1) { 269 // it's hydrogen, check its bonding and use its bond partner instead to request 270 // keysets 271 const BondList &ListOfBonds = surrogate->getListOfBonds(); 272 if ( ListOfBonds.size() != 1) { 273 ELOG(1, "Solitary hydrogen in atom " << surrogate->getId() << " detected, skipping."); 274 return 0.; 275 } 276 surrogate = (*ListOfBonds.begin())->GetOtherAtom(surrogate); 277 } 278 const atomId_t walkerid = surrogate->getId(); 279 const AtomFragmentsMap::AtomFragmentsMap_t &atommap = _atomfragments.getMap(); 280 const AtomFragmentsMap::AtomFragmentsMap_t::const_iterator keysetsiter = 281 atommap.find(walkerid); 282 ASSERT(keysetsiter != atommap.end(), 283 "fitAverageChargeToAtom() - we checked already that "+toString(walkerid) 284 +" should be present!"); 285 const AtomFragmentsMap::keysets_t & keysets = keysetsiter->second; 286 287 double average_charge = 0.; 288 size_t NoFragments = 0; 289 // go over all fragments associated to this atom 290 for (AtomFragmentsMap::keysets_t::const_iterator keysetsiter = keysets.begin(); 291 keysetsiter != keysets.end(); ++keysetsiter) { 292 const KeySet &keyset = *keysetsiter; 293 294 const AtomFragmentsMap::indices_t &forcekeyset = _atomfragments.getFullKeyset(keyset); 295 ASSERT( !forcekeyset.empty(), 296 "fitAverageChargeToAtom() - force keyset to "+toString(keyset)+" is empty."); 297 298 // find the associated charge in the charge vector 299 std::map<KeySet, HomologyGraph>::const_iterator keysetgraphiter = 300 _keyset_graphs.find(keyset); 301 ASSERT( keysetgraphiter != _keyset_graphs.end(), 302 "fitAverageChargeToAtom() - keyset "+toString(keyset) 303 +" not contained in keyset_graphs."); 304 const HomologyGraph &graph = keysetgraphiter->second; 305 const GraphFittedChargeMap_t::const_iterator chargesiter = 306 _fittedcharges_per_fragment.find(graph); 307 ASSERT(chargesiter != _fittedcharges_per_fragment.end(), 308 "fitAverageChargeToAtom() - no charge to "+toString(keyset) 309 +" any longer present in fittedcharges_per_fragment?"); 310 const PartialNucleiChargeFitter::charges_t &charges = chargesiter->second; 311 ASSERT( charges.size() == forcekeyset.size(), 312 "fitAverageChargeToAtom() - charges "+toString(charges.size())+" and keyset " 313 +toString(forcekeyset.size())+" do not have the same length?"); 314 PartialNucleiChargeFitter::charges_t::const_iterator chargeiter = 315 charges.begin(); 316 const AtomFragmentsMap::indices_t::const_iterator forcekeysetiter = 317 std::find(forcekeyset.begin(), forcekeyset.end(), _walker->getId()); 318 ASSERT( forcekeysetiter != forcekeyset.end(), 319 "fitAverageChargeToAtom() - atom "+toString(_walker->getId()) 320 +" not contained in force keyset "+toString(forcekeyset)); 321 std::advance(chargeiter, std::distance(forcekeyset.begin(), forcekeysetiter)); 322 323 // and add onto charge sum 324 const double & charge_in_fragment = *chargeiter; 325 average_charge += charge_in_fragment; 326 ++NoFragments; 327 } 328 // average to obtain final partial charge for this atom 329 average_charge *= 1./(double)NoFragments; 330 331 return average_charge; 332 } 333 334 void addToParticleRegistry( 335 const ParticleFactory &factory, 336 const periodentafel &periode, 337 const std::map<atomId_t, double> &_fitted_charges) 338 { 259 339 typedef std::map<atomId_t, double> fitted_charges_t; 260 fitted_charges_t fitted_charges; 261 for (World::AtomSelectionConstIterator atomiter = world.beginAtomSelection(); 262 atomiter != world.endAtomSelection(); ++atomiter) { 263 const atom * walker = atomiter->second; 264 if (walker->getElementNo() == 1) { 265 // it's hydrogen, check its bonding and use its bond partner instead to request 266 // keysets 267 const BondList &ListOfBonds = walker->getListOfBonds(); 268 if ( ListOfBonds.size() != 1) { 269 ELOG(1, "Solitary hydrogen in atom " << atomiter->first << " detected, skipping."); 270 continue; 271 } 272 walker = (*ListOfBonds.begin())->GetOtherAtom(walker); 273 } 274 const atomId_t walkerid = walker->getId(); 275 const AtomFragmentsMap::AtomFragmentsMap_t::const_iterator keysetsiter = 276 atommap.find(walkerid); 277 ASSERT(keysetsiter != atommap.end(), 278 "PotentialFitPartialChargesAction::performCall() - we checked already that " 279 +toString(walkerid)+" should be present!"); 280 const AtomFragmentsMap::keysets_t & keysets = keysetsiter->second; 281 282 double average_charge = 0.; 283 size_t NoFragments = 0; 284 // go over all fragments associated to this atom 285 for (AtomFragmentsMap::keysets_t::const_iterator keysetsiter = keysets.begin(); 286 keysetsiter != keysets.end(); ++keysetsiter) { 287 const KeySet &keyset = *keysetsiter; 288 289 const AtomFragmentsMap::indices_t &forcekeyset = atomfragments.getFullKeyset(keyset); 290 ASSERT( !forcekeyset.empty(), 291 "PotentialFitPartialChargesAction::performCall() - force keyset to " 292 +toString(keyset)+" is empty."); 293 294 // find the associated charge in the charge vector 295 const HomologyGraph &graph = keyset_graphs[keyset]; 296 const GraphFittedChargeMap_t::const_iterator chargesiter = 297 fittedcharges_per_fragment.find(graph); 298 ASSERT(chargesiter != fittedcharges_per_fragment.end(), 299 "PotentialFitPartialChargesAction::performCall() - no charge to "+toString(keyset) 300 +" any longer present in fittedcharges_per_fragment?"); 301 const PartialNucleiChargeFitter::charges_t &charges = chargesiter->second; 302 ASSERT( charges.size() == forcekeyset.size(), 303 "PotentialFitPartialChargesAction::performCall() - charges " 304 +toString(charges.size())+" and keyset "+toString(forcekeyset.size()) 305 +" do not have the same length?"); 306 PartialNucleiChargeFitter::charges_t::const_iterator chargeiter = 307 charges.begin(); 308 const AtomFragmentsMap::indices_t::const_iterator forcekeysetiter = 309 std::find(forcekeyset.begin(), forcekeyset.end(), atomiter->first); 310 ASSERT( forcekeysetiter != forcekeyset.end(), 311 "PotentialFitPartialChargesAction::performCall() - atom " 312 +toString(atomiter->first)+" not contained in force keyset "+toString(forcekeyset)); 313 std::advance(chargeiter, std::distance(forcekeyset.begin(), forcekeysetiter)); 314 315 // and add onto charge sum 316 const double & charge_in_fragment = *chargeiter; 317 average_charge += charge_in_fragment; 318 ++NoFragments; 319 } 320 // average to obtain final partial charge for this atom 321 average_charge *= 1./(double)NoFragments; 322 fitted_charges.insert( std::make_pair(atomiter->first, average_charge) ); 323 324 LOG(2, "DEBUG: For atom " << atomiter->first << " we have an average charge of " 325 << average_charge); 326 } 327 328 /// place all fitted charges into ParticleRegistry 329 const ParticleFactory &factory = 330 const_cast<const ParticleFactory&>(ParticleFactory::getInstance()); 331 const periodentafel &periode = *World::getInstance().getPeriode(); 332 for (fitted_charges_t::const_iterator chargeiter = fitted_charges.begin(); 333 chargeiter != fitted_charges.end(); ++chargeiter) { 340 for (fitted_charges_t::const_iterator chargeiter = _fitted_charges.begin(); 341 chargeiter != _fitted_charges.end(); ++chargeiter) { 334 342 const atom * const walker = World::getInstance().getAtom(AtomById(chargeiter->first)); 335 343 ASSERT( walker != NULL, … … 343 351 factory.createInstance(name, elementno, charge); 344 352 } 353 } 354 355 ActionState::ptr PotentialFitPartialChargesAction::performCall() 356 { 357 // check for selected atoms 358 const World &world = const_cast<const World &>(World::getInstance()); 359 if (world.beginAtomSelection() == world.endAtomSelection()) { 360 STATUS("There are no atoms selected for fitting partial charges to."); 361 return Action::failure; 362 } 363 364 /// obtain possible fragments to each selected atom 365 const AtomFragmentsMap &atomfragments = AtomFragmentsMap::getConstInstance(); 366 if (!atomfragments.checkCompleteness()) { 367 STATUS("AtomFragmentsMap failed internal consistency check, missing forcekeysets?"); 368 return Action::failure; 369 } 370 std::set<KeySet> fragments = 371 accumulateKeySetsForAtoms( atomfragments.getMap(), world.getSelectedAtoms()); 372 373 // reduce given fragments to homologous graphs to avoid multiple fittings 374 typedef std::map<KeySet, HomologyGraph> KeysetsToGraph_t; 375 KeysetsToGraph_t keyset_graphs; 376 typedef std::map<HomologyGraph, PartialNucleiChargeFitter::charges_t> GraphFittedChargeMap_t; 377 GraphFittedChargeMap_t fittedcharges_per_fragment; 378 getKeySetsToGraphMapping(keyset_graphs, fittedcharges_per_fragment, fragments, atomfragments); 379 380 /// then go through all fragments and get partial charges for each 381 const bool status = getPartialChargesForAllGraphs( 382 fittedcharges_per_fragment, 383 World::getInstance().getHomologies(), 384 params.radius.get(), 385 params.enforceZeroCharge.get()); 386 if (!status) 387 return Action::failure; 388 389 /// obtain average charge for each atom the fitted charges over all its fragments 390 typedef std::map<atomId_t, double> fitted_charges_t; 391 fitted_charges_t fitted_charges; 392 for (World::AtomSelectionConstIterator atomiter = world.beginAtomSelection(); 393 atomiter != world.endAtomSelection(); ++atomiter) { 394 const double average_charge = fitAverageChargeToAtom( 395 atomiter->second, atomfragments, keyset_graphs, fittedcharges_per_fragment); 396 397 if (average_charge != 0.) { 398 LOG(2, "DEBUG: For atom " << atomiter->first << " we have an average charge of " 399 << average_charge); 400 401 fitted_charges.insert( std::make_pair(atomiter->first, average_charge) ); 402 } 403 } 404 405 /// place all fitted charges into ParticleRegistry 406 addToParticleRegistry( 407 ParticleFactory::getConstInstance(), 408 *World::getInstance().getPeriode(), 409 fitted_charges); 345 410 346 411 return Action::success;
Note:
See TracChangeset
for help on using the changeset viewer.