27#ifndef N2P2_NO_SF_CACHE
37Mode::Mode() : nnpType (
NNPType::SHORT_ONLY),
39 checkExtrapolationWarnings(false ),
42 maxCutoffRadius (0.0 ),
53 log <<
"*****************************************"
54 "**************************************\n";
56 log <<
"WELCOME TO n²p², A SOFTWARE PACKAGE FOR NEURAL NETWORK "
58 log <<
"-------------------------------------------------------"
63 log <<
"------------------------------------------------------------\n";
66 log <<
"Compile date/time : " __DATE__
" " __TIME__
"\n";
67 log <<
"------------------------------------------------------------\n";
69 log <<
"Features/Flags:\n";
70 log <<
"------------------------------------------------------------\n";
71 log <<
"Symmetry function groups : ";
72#ifndef N2P2_NO_SF_GROUPS
77 log <<
"Symmetry function cache : ";
78#ifndef N2P2_NO_SF_CACHE
83 log <<
"Timing function available : ";
89 log <<
"Asymmetric polynomial SFs : ";
90#ifndef N2P2_NO_ASYM_POLY
95 log <<
"SF low neighbor number check : ";
96#ifndef N2P2_NO_NEIGH_CHECK
101 log <<
"SF derivative memory layout : ";
102#ifndef N2P2_FULL_SFD_MEMORY
107 log <<
"MPI explicitly disabled : ";
114 log <<
strpr(
"OpenMP threads : %d\n", omp_get_max_threads());
116 log <<
"------------------------------------------------------------\n";
119 log <<
"Please cite the following papers when publishing results "
120 "obtained with n²p²:\n";
121 log <<
"-----------------------------------------"
122 "--------------------------------------\n";
123 log <<
" * General citation for n²p² and the LAMMPS interface:\n";
125 log <<
" Singraber, A.; Behler, J.; Dellago, C.\n";
126 log <<
" Library-Based LAMMPS Implementation of High-Dimensional\n";
127 log <<
" Neural Network Potentials.\n";
128 log <<
" J. Chem. Theory Comput. 2019 15 (3), 1827–1840.\n";
129 log <<
" https://doi.org/10.1021/acs.jctc.8b00770\n";
130 log <<
"-----------------------------------------"
131 "--------------------------------------\n";
132 log <<
" * Additionally, if you use the NNP training features of n²p²:\n";
134 log <<
" Singraber, A.; Morawietz, T.; Behler, J.; Dellago, C.\n";
135 log <<
" Parallel Multistream Training of High-Dimensional Neural\n";
136 log <<
" Network Potentials.\n";
137 log <<
" J. Chem. Theory Comput. 2019, 15 (5), 3075–3092.\n";
138 log <<
" https://doi.org/10.1021/acs.jctc.8b01092\n";
139 log <<
"-----------------------------------------"
140 "--------------------------------------\n";
141 log <<
" * Additionally, if polynomial symmetry functions are used:\n";
143 log <<
" Bircher, M. P.; Singraber, A.; Dellago, C.\n";
144 log <<
" Improved Description of Atomic Environments Using Low-Cost\n";
145 log <<
" Polynomial Functions with Compact Support.\n";
146 log <<
" arXiv:2010.14414 [cond-mat, physics:physics] 2020.\n";
147 log <<
" https://arxiv.org/abs/2010.14414\n";
150 log <<
"*****************************************"
151 "**************************************\n";
159 log <<
"*** SETUP: SETTINGS FILE ****************"
160 "**************************************\n";
165 if (numCriticalProblems > 0)
167 throw runtime_error(
strpr(
"ERROR: %zu critical problem(s) were found "
168 "in settings file.\n", numCriticalProblems));
178 log <<
"This settings file defines a short-range only NNP.\n";
182 log <<
"This settings file defines a short-range NNP with additional "
183 "charge NN (method by M. Bircher).\n";
188 throw runtime_error(
"ERROR: Unknown NNP type.\n");
191 log <<
"*****************************************"
192 "**************************************\n";
204#ifndef N2P2_FULL_SFD_MEMORY
207#ifndef N2P2_NO_SF_CACHE
210#ifndef N2P2_NO_SF_GROUPS
223 log <<
"*** SETUP: NORMALIZATION ****************"
224 "**************************************\n";
236 log <<
"Data set normalization is used.\n";
243 log <<
"Atomic energy offsets are used in addition to"
244 " data set normalization.\n";
245 log <<
"Offsets will be subtracted from reference energies BEFORE"
246 " normalization is applied.\n";
254 log <<
"Data set normalization is not used.\n";
258 throw runtime_error(
"ERROR: Incorrect usage of normalization"
260 " Use all or none of \"mean_energy\", "
261 "\"conv_energy\" and \"conv_length\".\n");
266 log <<
"*****************************************"
267 "**************************************\n";
276 log <<
"*** SETUP: ELEMENT MAP ******************"
277 "**************************************\n";
288 log <<
"*****************************************"
289 "**************************************\n";
297 log <<
"*** SETUP: ELEMENTS *********************"
298 "**************************************\n";
304 throw runtime_error(
"ERROR: Inconsistent number of elements.\n");
316 for (Settings::KeyMap::const_iterator it = r.first;
317 it != r.second; ++it)
319 vector<string> args =
split(
reduce(it->second.first));
322 setAtomicEnergyOffset(atof(args.at(1).c_str()));
325 log <<
"Atomic energy offsets per element:\n";
328 log <<
strpr(
"Element %2zu: %16.8E\n",
329 i,
elements.at(i).getAtomicEnergyOffset());
332 log <<
"Energy offsets are automatically subtracted from reference "
334 log <<
"*****************************************"
335 "**************************************\n";
343 log <<
"*** SETUP: CUTOFF FUNCTIONS *************"
344 "**************************************\n";
355 throw invalid_argument(
"ERROR: 0 <= alpha < 1.0 is required.\n");
359 log <<
"Inner cutoff = Symmetry function cutoff * alpha\n";
361 log <<
"Equal cutoff function type for all symmetry functions:\n";
365 log <<
"x := (r - rc * alpha) / (rc - rc * alpha)\n";
366 log <<
"f(x) = 1/2 * (cos(pi*x) + 1)\n";
371 log <<
"f(r) = tanh^3(1 - r/rc)\n";
374 log <<
"WARNING: Inner cutoff parameter not used in combination"
375 " with this cutoff function.\n";
381 log <<
"f(r) = c * tanh^3(1 - r/rc), f(0) = 1\n";
384 log <<
"WARNING: Inner cutoff parameter not used in combination"
385 " with this cutoff function.\n";
391 log <<
"x := (r - rc * alpha) / (rc - rc * alpha)\n";
392 log <<
"f(x) = (2x - 3)x^2 + 1\n";
397 log <<
"x := (r - rc * alpha) / (rc - rc * alpha)\n";
398 log <<
"f(x) = ((15 - 6x)x - 10)x^3 + 1\n";
403 log <<
"x := (r - rc * alpha) / (rc - rc * alpha)\n";
404 log <<
"f(x) = (x(x(20x - 70) + 84) - 35)x^4 + 1\n";
409 log <<
"x := (r - rc * alpha) / (rc - rc * alpha)\n";
410 log <<
"f(x) = (x(x((315 - 70x)x - 540) + 420) - 126)x^5 + 1\n";
415 log <<
"x := (r - rc * alpha) / (rc - rc * alpha)\n";
416 log <<
"f(x) = exp(-1 / 1 - x^2)\n";
422 log <<
"WARNING: Hard cutoff used!\n";
426 throw invalid_argument(
"ERROR: Unknown cutoff type.\n");
429 log <<
"*****************************************"
430 "**************************************\n";
438 log <<
"*** SETUP: SYMMETRY FUNCTIONS ***********"
439 "**************************************\n";
443 for (Settings::KeyMap::const_iterator it = r.first; it != r.second; ++it)
445 vector<string> args =
split(
reduce(it->second.first));
448 elements.at(element).addSymmetryFunction(it->second.first,
452 log <<
"Abbreviations:\n";
453 log <<
"--------------\n";
454 log <<
"ind .... Symmetry function index.\n";
455 log <<
"ec ..... Central atom element.\n";
456 log <<
"tp ..... Symmetry function type.\n";
457 log <<
"sbtp ... Symmetry function subtype (e.g. cutoff type).\n";
458 log <<
"e1 ..... Neighbor 1 element.\n";
459 log <<
"e2 ..... Neighbor 2 element.\n";
460 log <<
"eta .... Gaussian width eta.\n";
461 log <<
"rs/rl... Shift distance of Gaussian or left cutoff radius "
463 log <<
"angl.... Left cutoff angle for polynomial.\n";
464 log <<
"angr.... Right cutoff angle for polynomial.\n";
465 log <<
"la ..... Angle prefactor lambda.\n";
466 log <<
"zeta ... Angle term exponent zeta.\n";
467 log <<
"rc ..... Cutoff radius / right cutoff radius for polynomial.\n";
468 log <<
"a ...... Free parameter alpha (e.g. cutoff alpha).\n";
469 log <<
"ln ..... Line number in settings file.\n";
472 for (vector<Element>::iterator it =
elements.begin();
476 it->sortSymmetryFunctions();
479 log <<
strpr(
"Short range atomic symmetry functions element %2s :\n",
480 it->getSymbol().c_str());
481 log <<
"--------------------------------------------------"
482 "-----------------------------------------------\n";
483 log <<
" ind ec tp sbtp e1 e2 eta rs/rl "
484 "rc angl angr la zeta a ln\n";
485 log <<
"--------------------------------------------------"
486 "-----------------------------------------------\n";
487 log << it->infoSymmetryFunctionParameters();
488 log <<
"--------------------------------------------------"
489 "-----------------------------------------------\n";
499 log <<
strpr(
"Minimum cutoff radius for element %2s: %f\n",
503 log <<
strpr(
"Maximum cutoff radius (global) : %f\n",
506 log <<
"*****************************************"
507 "**************************************\n";
515 log <<
"*** SETUP: SYMMETRY FUNCTION SCALING ****"
516 "**************************************\n";
519 log <<
"No scaling for symmetry functions.\n";
520 for (vector<Element>::iterator it =
elements.begin();
523 it->setScalingNone();
526 log <<
"*****************************************"
527 "**************************************\n";
535 log <<
"*** SETUP: SYMMETRY FUNCTION SCALING ****"
536 "**************************************\n";
539 log <<
"Equal scaling type for all symmetry functions:\n";
545 log <<
"Gs = Smin + (Smax - Smin) * (G - Gmin) / (Gmax - Gmin)\n";
552 log <<
"Gs = G - Gmean\n";
559 log <<
"Gs = Smin + (Smax - Smin) * (G - Gmean) / (Gmax - Gmin)\n";
565 log <<
"Gs = Smin + (Smax - Smin) * (G - Gmean) / Gsigma\n";
572 log <<
"WARNING: No symmetry function scaling!\n";
583 Smin = atof(
settings[
"scale_min_short"].c_str());
587 log <<
"WARNING: Keyword \"scale_min_short\" not found.\n";
588 log <<
" Default value for Smin = 0.0.\n";
594 Smax = atof(
settings[
"scale_max_short"].c_str());
598 log <<
"WARNING: Keyword \"scale_max_short\" not found.\n";
599 log <<
" Default value for Smax = 1.0.\n";
607 log <<
strpr(
"Symmetry function scaling statistics from file: %s\n",
609 log <<
"-----------------------------------------"
610 "--------------------------------------\n";
612 file.open(fileName.c_str());
615 throw runtime_error(
"ERROR: Could not open file: \"" + fileName
619 vector<string> lines;
620 while (getline(file, line))
622 if (line.at(0) !=
'#') lines.push_back(line);
627 log <<
"Abbreviations:\n";
628 log <<
"--------------\n";
629 log <<
"ind ..... Symmetry function index.\n";
630 log <<
"min ..... Minimum symmetry function value.\n";
631 log <<
"max ..... Maximum symmetry function value.\n";
632 log <<
"mean .... Mean symmetry function value.\n";
633 log <<
"sigma ... Standard deviation of symmetry function values.\n";
634 log <<
"sf ...... Scaling factor for derivatives.\n";
635 log <<
"Smin .... Desired minimum scaled symmetry function value.\n";
636 log <<
"Smax .... Desired maximum scaled symmetry function value.\n";
637 log <<
"t ....... Scaling type.\n";
639 for (vector<Element>::iterator it =
elements.begin();
643 log <<
strpr(
"Scaling data for symmetry functions element %2s :\n",
644 it->getSymbol().c_str());
645 log <<
"-----------------------------------------"
646 "--------------------------------------\n";
647 log <<
" ind min max mean sigma sf Smin Smax t\n";
648 log <<
"-----------------------------------------"
649 "--------------------------------------\n";
650 log << it->infoSymmetryFunctionScaling();
651 log <<
"-----------------------------------------"
652 "--------------------------------------\n";
653 lines.erase(lines.begin(), lines.begin() + it->numSymmetryFunctions());
656 log <<
"*****************************************"
657 "**************************************\n";
665 log <<
"*** SETUP: SYMMETRY FUNCTION GROUPS *****"
666 "**************************************\n";
669 log <<
"Abbreviations:\n";
670 log <<
"--------------\n";
671 log <<
"ind .... Symmetry function index.\n";
672 log <<
"ec ..... Central atom element.\n";
673 log <<
"tp ..... Symmetry function type.\n";
674 log <<
"sbtp ... Symmetry function subtype (e.g. cutoff type).\n";
675 log <<
"e1 ..... Neighbor 1 element.\n";
676 log <<
"e2 ..... Neighbor 2 element.\n";
677 log <<
"eta .... Gaussian width eta.\n";
678 log <<
"rs/rl... Shift distance of Gaussian or left cutoff radius "
680 log <<
"angl.... Left cutoff angle for polynomial.\n";
681 log <<
"angr.... Right cutoff angle for polynomial.\n";
682 log <<
"la ..... Angle prefactor lambda.\n";
683 log <<
"zeta ... Angle term exponent zeta.\n";
684 log <<
"rc ..... Cutoff radius / right cutoff radius for polynomial.\n";
685 log <<
"a ...... Free parameter alpha (e.g. cutoff alpha).\n";
686 log <<
"ln ..... Line number in settings file.\n";
687 log <<
"mi ..... Member index.\n";
688 log <<
"sfi .... Symmetry function index.\n";
689 log <<
"e ...... Recalculate exponential term.\n";
691 for (vector<Element>::iterator it =
elements.begin();
694 it->setupSymmetryFunctionGroups();
695 log <<
strpr(
"Short range atomic symmetry function groups "
696 "element %2s :\n", it->getSymbol().c_str());
697 log <<
"------------------------------------------------------"
698 "----------------------------------------------------\n";
699 log <<
" ind ec tp sbtp e1 e2 eta rs/rl "
700 "rc angl angr la zeta a ln mi sfi e\n";
701 log <<
"------------------------------------------------------"
702 "----------------------------------------------------\n";
703 log << it->infoSymmetryFunctionGroups();
704 log <<
"------------------------------------------------------"
705 "----------------------------------------------------\n";
708 log <<
"*****************************************"
709 "**************************************\n";
717 log <<
"*** SETUP: SYMMETRY FUNCTION MEMORY *****"
718 "**************************************\n";
723 e.setupSymmetryFunctionMemory();
724 vector<size_t> symmetryFunctionNumTable
725 = e.getSymmetryFunctionNumTable();
726 vector<vector<size_t>> symmetryFunctionTable
727 = e.getSymmetryFunctionTable();
728 log <<
strpr(
"Symmetry function derivatives memory table "
729 "for element %2s :\n", e.getSymbol().c_str());
730 log <<
"-----------------------------------------"
731 "--------------------------------------\n";
732 log <<
"Relevant symmetry functions for neighbors with element:\n";
735 log <<
strpr(
"- %2s: %4zu of %4zu (%5.1f %)\n",
737 symmetryFunctionNumTable.at(i),
738 e.numSymmetryFunctions(),
739 (100.0 * symmetryFunctionNumTable.at(i))
740 / e.numSymmetryFunctions());
743 log <<
"-----------------------------------------"
744 "--------------------------------------\n";
745 for (
auto isf : symmetryFunctionTable.at(i))
747 SymFnc const& sf = e.getSymmetryFunction(isf);
750 log <<
"-----------------------------------------"
751 "--------------------------------------\n";
754 log <<
"-----------------------------------------"
755 "--------------------------------------\n";
761 log <<
strpr(
"%2s - symmetry function per-element index table:\n",
762 e.getSymbol().c_str());
763 log <<
"-----------------------------------------"
764 "--------------------------------------\n";
771 log <<
"-----------------------------------------"
772 "--------------------------------------\n";
773 for (
size_t i = 0; i < e.numSymmetryFunctions(); ++i)
775 SymFnc const& sf = e.getSymmetryFunction(i);
780 if (ipe == numeric_limits<size_t>::max())
791 log <<
"-----------------------------------------"
792 "--------------------------------------\n";
797 log <<
"*****************************************"
798 "**************************************\n";
803#ifndef N2P2_NO_SF_CACHE
807 log <<
"*** SETUP: SYMMETRY FUNCTION CACHE ******"
808 "**************************************\n";
814 vector<vector<SFCacheList>> cacheLists(
numElements);
821 size_t ne = atoi(
split(identifier)[0].c_str());
823 for (
auto& c : cacheLists.at(ne))
825 if (identifier == c.identifier)
834 cacheLists.at(ne).push_back(SFCacheList());
835 cacheLists.at(ne).back().element = ne;
836 cacheLists.at(ne).back().identifier = identifier;
837 cacheLists.at(ne).back().indices.push_back(s.
getIndex());
843 log <<
strpr(
"Multiple cache identifiers for element %2s:\n\n",
846 double cacheUsageMean = 0.0;
847 size_t cacheCount = 0;
854 vector<SFCacheList>& c = cacheLists.at(j);
855 c.erase(remove_if(c.begin(),
859 return l.indices.size() <= 1;
861 cacheCount += c.size();
862 for (
size_t k = 0; k < c.size(); ++k)
864 cacheUsageMean += c.at(k).indices.size();
867 log <<
strpr(
"Cache %zu, Identifier \"%s\", "
868 "Symmetry functions",
869 k, c.at(k).identifier.c_str());
870 for (
auto si : c.at(k).indices)
905 cacheUsageMean /= cacheCount;
906 log <<
strpr(
"Element %2s: in total %zu caches, "
907 "used %3.2f times on average.\n",
908 e.
getSymbol().c_str(), cacheCount, cacheUsageMean);
911 log <<
"-----------------------------------------"
912 "--------------------------------------\n";
916 log <<
"*****************************************"
917 "**************************************\n";
924 bool collectExtrapolationWarnings,
925 bool writeExtrapolationWarnings,
926 bool stopOnExtrapolationWarnings)
929 log <<
"*** SETUP: SYMMETRY FUNCTION STATISTICS *"
930 "**************************************\n";
933 log <<
"Equal symmetry function statistics for all elements.\n";
934 log <<
strpr(
"Collect min/max/mean/sigma : %d\n",
935 (
int)collectStatistics);
936 log <<
strpr(
"Collect extrapolation warnings : %d\n",
937 (
int)collectExtrapolationWarnings);
938 log <<
strpr(
"Write extrapolation warnings immediately to stderr: %d\n",
939 (
int)writeExtrapolationWarnings);
940 log <<
strpr(
"Halt on any extrapolation warning : %d\n",
941 (
int)stopOnExtrapolationWarnings);
942 for (vector<Element>::iterator it =
elements.begin();
945 it->statistics.collectStatistics = collectStatistics;
946 it->statistics.collectExtrapolationWarnings =
947 collectExtrapolationWarnings;
948 it->statistics.writeExtrapolationWarnings = writeExtrapolationWarnings;
949 it->statistics.stopOnExtrapolationWarnings =
950 stopOnExtrapolationWarnings;
954 || collectExtrapolationWarnings
955 || writeExtrapolationWarnings
956 || stopOnExtrapolationWarnings;
958 log <<
"*****************************************"
959 "**************************************\n";
966 log <<
"*** SETUP: NEURAL NETWORKS **************"
967 "**************************************\n";
970 struct NeuralNetworkTopology
973 vector<int> numNeuronsPerLayer;
974 vector<NeuralNetwork::ActivationFunction> activationFunctionsPerLayer;
979 size_t globalNumHiddenLayers =
980 (size_t)atoi(
settings[
"global_hidden_layers_short"].c_str());
981 vector<string> globalNumNeuronsPerHiddenLayer =
983 vector<string> globalActivationFunctions =
988 NeuralNetworkTopology& t = nnt.at(i);
989 t.numLayers = 2 + globalNumHiddenLayers;
990 t.numNeuronsPerLayer.resize(t.numLayers, 0);
991 t.activationFunctionsPerLayer.resize(t.numLayers,
994 for (
int i = 0; i < t.numLayers; i++)
997 ActivationFunction& a = t.activationFunctionsPerLayer[i];
1000 t.numNeuronsPerLayer[i] = 0;
1005 if (i == t.numLayers - 1) t.numNeuronsPerLayer[i] = 1;
1008 t.numNeuronsPerLayer[i] =
1009 atoi(globalNumNeuronsPerHiddenLayer.at(i-1).c_str());
1011 if (globalActivationFunctions.at(i-1) ==
"l")
1015 else if (globalActivationFunctions.at(i-1) ==
"t")
1019 else if (globalActivationFunctions.at(i-1) ==
"s")
1023 else if (globalActivationFunctions.at(i-1) ==
"p")
1027 else if (globalActivationFunctions.at(i-1) ==
"r")
1031 else if (globalActivationFunctions.at(i-1) ==
"g")
1035 else if (globalActivationFunctions.at(i-1) ==
"c")
1039 else if (globalActivationFunctions.at(i-1) ==
"S")
1043 else if (globalActivationFunctions.at(i-1) ==
"e")
1047 else if (globalActivationFunctions.at(i-1) ==
"h")
1053 throw runtime_error(
"ERROR: Unknown activation "
1063 for (Settings::KeyMap::const_iterator it = r.first;
1064 it != r.second; ++it)
1066 vector<string> args =
split(
reduce(it->second.first));
1068 size_t l = atoi(args.at(1).c_str());
1070 nnt.at(e).numNeuronsPerLayer.at(l) =
1071 (size_t)atoi(args.at(2).c_str());
1076 log <<
strpr(
"Normalize neurons (all elements): %d\n",
1077 (
int)normalizeNeurons);
1078 log <<
"-----------------------------------------"
1079 "--------------------------------------\n";
1084 NeuralNetworkTopology& t = nnt.at(i);
1090 forward_as_tuple(
"short"),
1093 t.numNeuronsPerLayer.data(),
1094 t.activationFunctionsPerLayer.data()));
1095 e.
neuralNetworks.at(
"short").setNormalizeNeurons(normalizeNeurons);
1096 log <<
strpr(
"Atomic short range NN for "
1097 "element %2s :\n", e.
getSymbol().c_str());
1099 log <<
"-----------------------------------------"
1100 "--------------------------------------\n";
1104 piecewise_construct,
1105 forward_as_tuple(
"charge"),
1108 t.numNeuronsPerLayer.data(),
1109 t.activationFunctionsPerLayer.data()));
1111 .setNormalizeNeurons(normalizeNeurons);
1112 log <<
strpr(
"Atomic charge NN for "
1113 "element %2s :\n", e.
getSymbol().c_str());
1115 log <<
"-----------------------------------------"
1116 "--------------------------------------\n";
1120 log <<
"*****************************************"
1121 "**************************************\n";
1127 string const& fileNameFormatCharge)
1130 log <<
"*** SETUP: NEURAL NETWORK WEIGHTS *******"
1131 "**************************************\n";
1134 log <<
strpr(
"Short NN weight file name format: %s\n",
1135 fileNameFormatShort.c_str());
1139 log <<
strpr(
"Charge NN weight file name format: %s\n",
1140 fileNameFormatCharge.c_str());
1144 log <<
"*****************************************"
1145 "**************************************\n";
1151 bool const derivatives)
1160 #pragma omp parallel for private (a, e)
1162 for (
size_t i = 0; i < structure.
atoms.size(); ++i)
1165 a = &(structure.
atoms.at(i));
1182#ifndef N2P2_NO_SF_CACHE
1186#ifndef N2P2_NO_NEIGH_CHECK
1192 log <<
strpr(
"WARNING: Structure %6zu Atom %6zu : %zu "
1215 for (
size_t i = 0; i < structure.
atoms.size(); ++i)
1217 a = &(structure.
atoms.at(i));
1231 bool const derivatives)
1240 #pragma omp parallel for private (a, e)
1242 for (
size_t i = 0; i < structure.
atoms.size(); ++i)
1245 a = &(structure.
atoms.at(i));
1262#ifndef N2P2_NO_SF_CACHE
1266#ifndef N2P2_NO_NEIGH_CHECK
1272 log <<
strpr(
"WARNING: Structure %6zu Atom %6zu : %zu "
1295 for (
size_t i = 0; i < structure.
atoms.size(); ++i)
1297 a = &(structure.
atoms.at(i));
1311 bool const derivatives)
1315 for (vector<Atom>::iterator it = structure.
atoms.begin();
1316 it != structure.
atoms.end(); ++it)
1319 .neuralNetworks.at(
"short");
1331 for (vector<Atom>::iterator it = structure.
atoms.begin();
1332 it != structure.
atoms.end(); ++it)
1336 .neuralNetworks.at(
"charge");
1337 nnCharge.
setInput(&((it->G).front()));
1347 .neuralNetworks.at(
"short");
1348 for (
size_t i = 0; i < it->G.size(); ++i)
1353 nnShort.
setInput(it->G.size(), it->charge);
1370 for (vector<Atom>::iterator it = structure.
atoms.begin();
1371 it != structure.
atoms.end(); ++it)
1373 structure.
energy += it->energy;
1383 for (vector<Atom>::iterator it = structure.
atoms.begin();
1384 it != structure.
atoms.end(); ++it)
1386 structure.
charge += it->charge;
1397 #pragma omp parallel for private(ai)
1399 for (
size_t i = 0; i < structure.
atoms.size(); ++i)
1402 ai = &(structure.
atoms.at(i));
1413 ai->
f -= ai->
dEdG.at(j) * ai->
dGdr.at(j);
1430#ifndef N2P2_FULL_SFD_MEMORY
1431 vector<vector<size_t> >
const& tableFull
1435 for (vector<Atom::Neighbor>::const_iterator n =
1439 if (n->index == ai->
index)
1441#ifndef N2P2_FULL_SFD_MEMORY
1442 vector<size_t>
const& table = tableFull.at(n->element);
1443 for (
size_t j = 0; j < n->dGdr.size(); ++j)
1445 ai->
f -= aj.
dEdG.at(table.at(j)) * n->dGdr.at(j);
1450 ai->
f -= aj.
dEdG.at(j) * n->dGdr.at(j);
1468 *
elements.at(i).getAtomicEnergyOffset();
1473 *
elements.at(i).getAtomicEnergyOffset();
1487 *
elements.at(i).getAtomicEnergyOffset();
1492 *
elements.at(i).getAtomicEnergyOffset();
1501 double result = 0.0;
1506 *
elements.at(i).getAtomicEnergyOffset();
1516 else result = structure.
energy;
1521 *
elements.at(i).getAtomicEnergyOffset();
1529 if (property ==
"energy")
return value *
convEnergy;
1531 else throw runtime_error(
"ERROR: Unknown property to convert to "
1532 "normalized units.\n");
1551 if (property ==
"energy")
return value /
convEnergy;
1553 else throw runtime_error(
"ERROR: Unknown property to convert to physical "
1586 for (vector<Element>::iterator it =
elements.begin();
1589 it->statistics.resetExtrapolationWarnings();
1597 size_t numExtrapolationWarnings = 0;
1599 for (vector<Element>::const_iterator it =
elements.begin();
1602 numExtrapolationWarnings +=
1603 it->statistics.countExtrapolationWarnings();
1606 return numExtrapolationWarnings;
1613 for (vector<Element>::const_iterator it =
elements.begin();
1616 v.push_back(it->numSymmetryFunctions());
1635 ofstream file(fileName.c_str());
1637 for (
size_t i = 0; i < settingsLines.size(); ++i)
1639 if (find(prune.begin(), prune.end(), i) != prune.end())
1643 file << settingsLines.at(i) <<
'\n';
1659 vector<size_t> prune;
1662 for (vector<Element>::const_iterator it =
elements.begin();
1665 for (
size_t i = 0; i < it->numSymmetryFunctions(); ++i)
1667 SymFnc const& s = it->getSymmetryFunction(i);
1670 prune.push_back(it->getSymmetryFunction(i).getLineNumber());
1680 vector<vector<double> > sensitivity)
1682 vector<size_t> prune;
1686 for (
size_t j = 0; j <
elements.at(i).numSymmetryFunctions(); ++j)
1688 if (sensitivity.at(i).at(j) < threshold)
1691 elements.at(i).getSymmetryFunction(j).getLineNumber());
1700 string const& fileNameFormat)
1703 if (type ==
"short" ) s =
"short NN";
1704 else if (type ==
"charge") s =
"charge NN";
1707 throw runtime_error(
"ERROR: Unknown neural network type.\n");
1710 for (vector<Element>::iterator it =
elements.begin();
1713 string fileName =
strpr(fileNameFormat.c_str(),
1714 it->getAtomicNumber());
1715 log <<
strpr(
"Setting %s weights for element %2s from file: %s\n",
1717 it->getSymbol().c_str(),
1720 vector<size_t>(1, 0)
CutoffType
List of available cutoff function types.
std::size_t registerElements(std::string const &elementLine)
Extract all elements and store in element map.
std::size_t size() const
Get element map size.
std::size_t atomicNumber(std::size_t index) const
Get atomic number from element index.
Contains element-specific data.
void calculateSymmetryFunctions(Atom &atom, bool const derivatives) const
Calculate symmetry functions.
void calculateSymmetryFunctionGroups(Atom &atom, bool const derivatives) const
Calculate symmetry functions via groups.
std::vector< std::size_t > getCacheSizes() const
Get cache sizes for each neighbor atom element.
std::size_t getIndex() const
Get index.
void setCacheIndices(std::vector< std::vector< SFCacheList > > cacheLists)
Set cache indices for all symmetry functions of this element.
std::size_t updateSymmetryFunctionStatistics(Atom const &atom)
Update symmetry function statistics.
SymFnc const & getSymmetryFunction(std::size_t index) const
Get symmetry function instance.
std::string getSymbol() const
Get symbol.
std::map< std::string, NeuralNetwork > neuralNetworks
Neural networks for this element.
std::size_t numSymmetryFunctions() const
Get number of symmetry functions.
std::vector< std::size_t > const & getSymmetryFunctionNumTable() const
Get number of relevant symmetry functions per element.
double physicalEnergy(Structure const &structure, bool ref=true) const
Undo normalization for a given energy of structure.
bool checkExtrapolationWarnings
void setupNormalization(bool standalone=true)
Set up normalization.
ElementMap elementMap
Global element map, populated by setupElementMap().
std::vector< double > minCutoffRadius
void addEnergyOffset(Structure &structure, bool ref=true)
Add atomic energy offsets to reference energy.
void initialize()
Write welcome message with version information.
virtual void setupElementMap()
Set up the element map.
virtual void setupNeuralNetwork()
Set up neural networks for all elements.
virtual void setupSymmetryFunctionCache(bool verbose=false)
Set up symmetry function cache.
@ SHORT_CHARGE_NN
Short range NNP with additional charge NN (M. Bircher).
@ SHORT_ONLY
Short range NNP only.
void readNeuralNetworkWeights(std::string const &type, std::string const &fileName)
Read in weights for a specific type of neural network.
std::vector< std::size_t > pruneSymmetryFunctionsRange(double threshold)
Prune symmetry functions according to their range and write settings file.
SymFnc::ScalingType scalingType
double physical(std::string const &property, double value) const
Undo normalization for a given property.
void writePrunedSettingsFile(std::vector< std::size_t > prune, std::string fileName="output.nn") const
Copy settings file but comment out lines provided.
virtual void setupSymmetryFunctionGroups()
Set up symmetry function groups.
std::vector< Element > elements
double normalized(std::string const &property, double value) const
Apply normalization to given property.
void calculateAtomicNeuralNetworks(Structure &structure, bool const derivatives)
Calculate a single atomic neural network for a given atom and nn type.
virtual void setupNeuralNetworkWeights(std::string const &fileNameFormatShort="weights.%03zu.data", std::string const &fileNameFormatCharge="weightse.%03zu.data")
Set up neural network weights from files.
void convertToNormalizedUnits(Structure &structure) const
Convert one structure to normalized units.
void calculateEnergy(Structure &structure) const
Calculate potential energy for a given structure.
void calculateSymmetryFunctionGroups(Structure &structure, bool const derivatives)
Calculate all symmetry function groups for all atoms in given structure.
void setupSymmetryFunctionScalingNone()
Set up "empy" symmetry function scaling.
std::string settingsGetValue(std::string const &keyword) const
Get value for given keyword in Settings instance.
virtual void setupSymmetryFunctionScaling(std::string const &fileName="scaling.data")
Set up symmetry function scaling from file.
std::vector< std::size_t > getNumSymmetryFunctions() const
Get number of symmetry functions per element.
std::size_t getNumExtrapolationWarnings() const
Count total number of extrapolation warnings encountered for all elements and symmetry functions.
void removeEnergyOffset(Structure &structure, bool ref=true)
Remove atomic energy offsets from reference energy.
bool settingsKeywordExists(std::string const &keyword) const
Check if keyword was found in settings file.
void resetExtrapolationWarnings()
Erase all extrapolation warnings and reset counters.
double getEnergyWithOffset(Structure const &structure, bool ref=true) const
Add atomic energy offsets and return energy.
void setupGeneric(bool skipNormalize=false)
Combine multiple setup routines and provide a basic NNP setup.
std::vector< std::size_t > minNeighbors
void convertToPhysicalUnits(Structure &structure) const
Convert one structure to physical units.
void calculateCharge(Structure &structure) const
Calculate total charge for a given structure.
virtual void setupSymmetryFunctions()
Set up all symmetry functions.
void calculateSymmetryFunctions(Structure &structure, bool const derivatives)
Calculate all symmetry functions for all atoms in given structure.
void calculateForces(Structure &structure) const
Calculate forces for all atoms in given structure.
void setupSymmetryFunctionStatistics(bool collectStatistics, bool collectExtrapolationWarnings, bool writeExtrapolationWarnings, bool stopOnExtrapolationWarnings)
Set up symmetry function statistics collection.
void setupCutoff()
Set up cutoff function for all symmetry functions.
void loadSettingsFile(std::string const &fileName="input.nn")
Open settings file and load all keywords into memory.
std::vector< std::size_t > pruneSymmetryFunctionsSensitivity(double threshold, std::vector< std::vector< double > > sensitivity)
Prune symmetry functions with sensitivity analysis data.
double getEnergyOffset(Structure const &structure) const
Get atomic energy offset for given structure.
void setupSymmetryFunctionMemory(bool verbose=false)
Extract required memory dimensions for symmetry function derivatives.
void writeSettingsFile(std::ofstream *const &file) const
Write complete settings file.
double normalizedEnergy(Structure const &structure, bool ref=true) const
Apply normalization to given energy of structure.
CutoffFunction::CutoffType cutoffType
virtual void setupElements()
Set up all Element instances.
This class implements a feed-forward neural network.
@ AF_RELU
(NOT recommended for HDNNPs!)
void setInput(double const *const &input) const
Set neural network input layer node values.
void setConnections(double const *const &connections)
Set neural network weights and biases.
void propagate()
Propagate input information through all layers.
void calculateDEdG(double *dEdG) const
Calculate derivative of output neuron with respect to input neurons.
void getOutput(double *output) const
Get neural network output layer node values.
std::vector< std::string > info() const
Get logged information about settings file.
void writeSettingsFile(std::ofstream *const &file, std::map< std::size_t, std::string > const &replacements={}) const
Write complete settings file.
bool keywordExists(std::string const &keyword, bool exact=false) const
Check if keyword is present in settings file.
std::size_t loadFile(std::string const &fileName="input.nn")
Load a file with settings.
KeyRange getValues(std::string const &keyword) const
Get all keyword-value pairs for given keyword.
std::string getValue(std::string const &keyword) const
Get value for given keyword.
std::vector< std::string > getSettingsLines() const
Get complete settings file.
std::pair< KeyMap::const_iterator, KeyMap::const_iterator > KeyRange
Symmetry function base class.
virtual std::string parameterLine() const =0
Give symmetry function parameters in one line.
double getGmin() const
Get private Gmin member variable.
double getGmax() const
Get private Gmax member variable.
std::vector< std::size_t > getIndexPerElement() const
Get private indexPerElement member variable.
virtual std::vector< std::string > getCacheIdentifiers() const
Get unique cache identifiers.
std::size_t getIndex() const
Get private index member variable.
string strpr(const char *format,...)
String version of printf function.
vector< string > split(string const &input, char delimiter)
Split string at each delimiter.
map< size_t, vector< double > > readColumnsFromFile(string fileName, vector< size_t > columns, char comment)
string reduce(string const &line, string const &whitespace, string const &fill)
Replace multiple whitespaces with fill.
Storage for a single atom.
std::vector< Neighbor > neighbors
Neighbor array (maximum number defined in macros.h.
std::size_t numSymmetryFunctions
Number of symmetry functions used to describe the atom environment.
std::vector< double > dEdG
Derivative of atomic energy with respect to symmetry functions.
Vec3D f
Force vector calculated by neural network.
bool hasSymmetryFunctionDerivatives
If symmetry function derivatives are saved for this atom.
void allocate(bool all)
Allocate vectors related to symmetry functions (G, dEdG).
std::size_t index
Index number of this atom.
std::vector< std::size_t > numSymmetryFunctionDerivatives
Number of neighbor atom symmetry function derivatives per element.
bool useChargeNeuron
If an additional charge neuron in the short-range NN is present.
std::vector< Vec3D > dGdr
Derivative of symmetry functions with respect to this atom's coordinates.
std::size_t indexStructure
Index number of structure this atom belongs to.
std::size_t element
Element index of this atom.
bool hasSymmetryFunctions
If symmetry function values are saved for this atom.
std::vector< std::size_t > cacheSizePerElement
Cache size for each element.
std::vector< std::size_t > neighborsUnique
List of unique neighbor indices (don't count multiple PBC images).
std::size_t getNumNeighbors(double cutoffRadius) const
Calculate number of neighbors for a given cutoff radius.
List of symmetry functions corresponding to one cache identifier.
Storage for one atomic configuration.
void toPhysicalUnits(double meanEnergy, double convEnergy, double convLength)
Switch to physical units, shift energy and change energy and length unit.
std::vector< std::size_t > numAtomsPerElement
Number of atoms of each element in this structure.
double charge
Charge determined by neural network potential.
bool hasSymmetryFunctionDerivatives
If symmetry function derivatives are saved for each atom.
double energy
Potential energy determined by neural network.
double energyRef
Reference potential energy.
void toNormalizedUnits(double meanEnergy, double convEnergy, double convLength)
Normalize structure, shift energy and change energy and length unit.
std::size_t numAtoms
Total number of atoms present in this structure.
std::vector< Atom > atoms
Vector of all atoms in this structure.
bool hasSymmetryFunctions
If symmetry function values are saved for each atom.