n2p2 - A neural network potential package
ModeCabana_impl.h
Go to the documentation of this file.
1// n2p2 - A neural network potential package
2// Copyright (C) 2018 Andreas Singraber (University of Vienna)
3// Copyright (C) 2020 Saaketh Desai and Sam Reeve
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18#include "utility.h"
19
20#include <algorithm> // std::min, std::max
21#include <cstdlib> // atoi, atof
22#include <fstream> // std::ifstream
23#include <limits> // std::numeric_limits
24#include <stdexcept> // std::runtime_error
25#include <string>
26
27using namespace std;
28
29namespace nnp
30{
31
32// TODO: call base, then copy to Views
33template <class t_device>
35{
36 log << "\n";
37 log << "*** SETUP: ELEMENT MAP ******************"
38 "**************************************\n";
39 log << "\n";
40
41 elementStrings = split( reduce( settings["elements"] ) );
42
43 log << strpr( "Number of element strings found: %d\n",
44 elementStrings.size() );
45 for ( size_t i = 0; i < elementStrings.size(); ++i )
46 {
47 log << strpr( "Element %2zu: %2s\n", i,
48 elementStrings[i].c_str() );
49 }
50 // resize to match number of element types
51 numElements = elementStrings.size();
52
53 log << "*****************************************"
54 "**************************************\n";
55
56 return;
57}
58
59template <class t_device>
61{
62 log << "\n";
63 log << "*** SETUP: ELEMENTS *********************"
64 "**************************************\n";
65 log << "\n";
66
67 numElements = (size_t)atoi( settings["number_of_elements"].c_str() );
68 atomicEnergyOffset =
69 h_t_mass( "Mode::atomicEnergyOffset", numElements );
70 if ( numElements != elementStrings.size() )
71 {
72 throw runtime_error( "ERROR: Inconsistent number of elements.\n" );
73 }
74 log << strpr( "Number of elements is consistent: %zu\n", numElements );
75
76 for ( size_t i = 0; i < numElements; ++i )
77 {
78 elements.push_back( ElementCabana( i ) );
79 }
80
81 if ( settings.keywordExists( "atom_energy" ) )
82 {
83 Settings::KeyRange r = settings.getValues( "atom_energy" );
84 for ( Settings::KeyMap::const_iterator it = r.first;
85 it != r.second; ++it )
86 {
87 vector<string> args = split( reduce( it->second.first ) );
88 const char *estring = args.at( 0 ).c_str();
89 for ( size_t i = 0; i < elementStrings.size(); ++i )
90 {
91 if ( strcmp( elementStrings[i].c_str(), estring ) == 0 )
92 atomicEnergyOffset( i ) = atof( args.at( 1 ).c_str() );
93 }
94 }
95 }
96
97 log << "Atomic energy offsets per element:\n";
98 for ( size_t i = 0; i < elementStrings.size(); ++i )
99 {
100 log << strpr( "Element %2zu: %16.8E\n", i,
101 atomicEnergyOffset( i ) );
102 }
103
104 log << "Energy offsets are automatically subtracted from reference "
105 "energies.\n";
106 log << "*****************************************"
107 "**************************************\n";
108
109 return;
110}
111
112template <class t_device>
114{
115 maxSFperElem = 0;
116 h_numSFperElem =
117 h_t_int( "Mode::numSymmetryFunctionsPerElement", numElements );
118 log << "\n";
119 log << "*** SETUP: SYMMETRY FUNCTIONS ***********"
120 "**************************************\n";
121 log << "\n";
122
123 // Only count SF per element; parse and add later
124 Settings::KeyRange r = settings.getValues( "symfunction_short" );
125 for ( Settings::KeyMap::const_iterator it = r.first; it != r.second;
126 ++it )
127 {
128 vector<string> args = split( reduce( it->second.first ) );
129 int type = 0;
130 const char *estring = args.at( 0 ).c_str();
131 for ( size_t i = 0; i < elementStrings.size(); ++i )
132 {
133 if ( strcmp( elementStrings[i].c_str(), estring ) == 0 )
134 type = i;
135 }
136 h_numSFperElem( type )++;
137
138 if ( h_numSFperElem( type ) > maxSFperElem )
139 maxSFperElem = h_numSFperElem( type );
140 }
141 Kokkos::deep_copy( h_numSFperElem, 0 );
142
143 // setup SF host views
144 // create device mirrors if needed below
145 SF = t_SF( "SymmetryFunctions", numElements, maxSFperElem );
146 SFscaling = t_SFscaling( "SFscaling", numElements, maxSFperElem );
147 // +1 to store size of memberlist
148 SFGmemberlist = t_SFGmemberlist( "SFGmemberlist", numElements,
149 maxSFperElem + 1, maxSFperElem + 1 );
150
151 r = settings.getValues( "symfunction_short" );
152 for ( Settings::KeyMap::const_iterator it = r.first; it != r.second;
153 ++it )
154 {
155 vector<string> args = split( reduce( it->second.first ) );
156 int type = 0;
157 const char *estring = args.at( 0 ).c_str();
158 for ( size_t i = 0; i < elementStrings.size(); ++i )
159 {
160 if ( strcmp( elementStrings[i].c_str(), estring ) == 0 )
161 type = i;
162 }
163 elements.at( type ).addSymmetryFunction( it->second.first,
164 elementStrings, type, SF,
165 convLength, h_numSFperElem );
166 }
167
168 log << "Abbreviations:\n";
169 log << "--------------\n";
170 log << "ind .... Symmetry function index.\n";
171 log << "ec ..... Central atom element.\n";
172 log << "ty ..... Symmetry function type.\n";
173 log << "e1 ..... Neighbor 1 element.\n";
174 log << "e2 ..... Neighbor 2 element.\n";
175 log << "eta .... Gaussian width eta.\n";
176 log << "rs ..... Shift distance of Gaussian.\n";
177 log << "la ..... Angle prefactor lambda.\n";
178 log << "zeta ... Angle term exponent zeta.\n";
179 log << "rc ..... Cutoff radius.\n";
180 log << "ct ..... Cutoff type.\n";
181 log << "ca ..... Cutoff alpha.\n";
182 log << "ln ..... Line number in settings file.\n";
183 log << "\n";
184 maxCutoffRadius = 0.0;
185
186 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
187 ++it )
188 {
189 int attype = it->getIndex();
190 it->sortSymmetryFunctions( SF, h_numSFperElem, attype );
191 maxCutoffRadius =
192 max( it->getMaxCutoffRadius( SF, attype, h_numSFperElem ),
193 maxCutoffRadius );
194 it->setCutoffFunction( cutoffType, cutoffAlpha, SF, attype,
195 h_numSFperElem );
196 log << strpr(
197 "Short range atomic symmetry functions element %2s :\n",
198 it->getSymbol().c_str() );
199 log << "-----------------------------------------"
200 "--------------------------------------\n";
201 log << " ind ec ty e1 e2 eta rs la "
202 "zeta rc ct ca ln\n";
203 log << "-----------------------------------------"
204 "--------------------------------------\n";
205 log << it->infoSymmetryFunctionParameters( SF, attype, h_numSFperElem );
206 log << "-----------------------------------------"
207 "--------------------------------------\n";
208 }
209 minNeighbors.resize( numElements, 0 );
210 minCutoffRadius.resize( numElements, maxCutoffRadius );
211 for ( size_t i = 0; i < numElements; ++i )
212 {
213 int attype = elements.at( i ).getIndex();
214 int nSF = h_numSFperElem( attype );
215 minNeighbors.at( i ) =
216 elements.at( i ).getMinNeighbors( attype, SF, nSF );
217 minCutoffRadius.at( i ) =
218 elements.at( i ).getMinCutoffRadius( SF, attype, h_numSFperElem );
219 log << strpr( "Minimum cutoff radius for element %2s: %f\n",
220 elements.at( i ).getSymbol().c_str(),
221 minCutoffRadius.at( i ) / convLength );
222 }
223 log << strpr( "Maximum cutoff radius (global) : %f\n",
224 maxCutoffRadius / convLength );
225
226 log << "*****************************************"
227 "**************************************\n";
228
229 numSFperElem =
230 Kokkos::create_mirror_view_and_copy( memory_space(), h_numSFperElem );
231
232 return;
233}
234
235// TODO: call base, then copy to View
236template <class t_device>
238{
239 log << "\n";
240 log << "*** SETUP: SYMMETRY FUNCTION SCALING ****"
241 "**************************************\n";
242 log << "\n";
243
244 log << "Equal scaling type for all symmetry functions:\n";
245 if ( ( settings.keywordExists( "scale_symmetry_functions" ) ) &&
246 ( !settings.keywordExists( "center_symmetry_functions" ) ) )
247 {
248 scalingType = ST_SCALE;
249 log << strpr( "Scaling type::ST_SCALE (%d)\n", scalingType );
250 log << "Gs = Smin + (Smax - Smin) * (G - Gmin) / (Gmax - Gmin)\n";
251 }
252 else if ( ( !settings.keywordExists( "scale_symmetry_functions" ) ) &&
253 ( settings.keywordExists( "center_symmetry_functions" ) ) )
254 {
255 scalingType = ST_CENTER;
256 log << strpr( "Scaling type::ST_CENTER (%d)\n", scalingType );
257 log << "Gs = G - Gmean\n";
258 }
259 else if ( ( settings.keywordExists( "scale_symmetry_functions" ) ) &&
260 ( settings.keywordExists( "center_symmetry_functions" ) ) )
261 {
262 scalingType = ST_SCALECENTER;
263 log << strpr( "Scaling type::ST_SCALECENTER (%d)\n", scalingType );
264 log << "Gs = Smin + (Smax - Smin) * (G - Gmean) / (Gmax - Gmin)\n";
265 }
266 else if ( settings.keywordExists( "scale_symmetry_functions_sigma" ) )
267 {
268 scalingType = ST_SCALESIGMA;
269 log << strpr( "Scaling type::ST_SCALESIGMA (%d)\n", scalingType );
270 log << "Gs = Smin + (Smax - Smin) * (G - Gmean) / Gsigma\n";
271 }
272 else
273 {
274 scalingType = ST_NONE;
275 log << strpr( "Scaling type::ST_NONE (%d)\n", scalingType );
276 log << "Gs = G\n";
277 log << "WARNING: No symmetry function scaling!\n";
278 }
279
280 double Smin = 0.0;
281 double Smax = 0.0;
282 if ( scalingType == ST_SCALE || scalingType == ST_SCALECENTER ||
283 scalingType == ST_SCALESIGMA )
284 {
285 if ( settings.keywordExists( "scale_min_short" ) )
286 {
287 Smin = atof( settings["scale_min_short"].c_str() );
288 }
289 else
290 {
291 log << "WARNING: Keyword \"scale_min_short\" not found.\n";
292 log << " Default value for Smin = 0.0.\n";
293 Smin = 0.0;
294 }
295
296 if ( settings.keywordExists( "scale_max_short" ) )
297 {
298 Smax = atof( settings["scale_max_short"].c_str() );
299 }
300 else
301 {
302 log << "WARNING: Keyword \"scale_max_short\" not found.\n";
303 log << " Default value for Smax = 1.0.\n";
304 Smax = 1.0;
305 }
306
307 log << strpr( "Smin = %f\n", Smin );
308 log << strpr( "Smax = %f\n", Smax );
309 }
310
311 log << strpr( "Symmetry function scaling statistics from file: %s\n",
312 fileName.c_str() );
313 log << "-----------------------------------------"
314 "--------------------------------------\n";
315 ifstream file;
316 file.open( fileName.c_str() );
317 if ( !file.is_open() )
318 {
319 throw runtime_error( "ERROR: Could not open file: \"" + fileName +
320 "\".\n" );
321 }
322 string line;
323 vector<string> lines;
324 while ( getline( file, line ) )
325 {
326 if ( line.at( 0 ) != '#' )
327 lines.push_back( line );
328 }
329 file.close();
330
331 log << "\n";
332 log << "Abbreviations:\n";
333 log << "--------------\n";
334 log << "ind ..... Symmetry function index.\n";
335 log << "min ..... Minimum symmetry function value.\n";
336 log << "max ..... Maximum symmetry function value.\n";
337 log << "mean .... Mean symmetry function value.\n";
338 log << "sigma ... Standard deviation of symmetry function values.\n";
339 log << "sf ...... Scaling factor for derivatives.\n";
340 log << "Smin .... Desired minimum scaled symmetry function value.\n";
341 log << "Smax .... Desired maximum scaled symmetry function value.\n";
342 log << "t ....... Scaling type.\n";
343 log << "\n";
344 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
345 ++it )
346 {
347 int attype = it->getIndex();
348 it->setScaling( scalingType, lines, Smin, Smax, SF, SFscaling, attype,
349 h_numSFperElem );
350 log << strpr(
351 "Scaling data for symmetry functions element %2s :\n",
352 it->getSymbol().c_str() );
353 log << "-----------------------------------------"
354 "--------------------------------------\n";
355 log << " ind min max mean sigma sf Smin "
356 "Smax t\n";
357 log << "-----------------------------------------"
358 "--------------------------------------\n";
359 log << it->infoSymmetryFunctionScaling( scalingType, SF, SFscaling,
360 attype, h_numSFperElem );
361 log << "-----------------------------------------"
362 "--------------------------------------\n";
363 lines.erase( lines.begin(),
364 lines.begin() +
365 it->numSymmetryFunctions( attype, h_numSFperElem ) );
366 }
367
368 log << "*****************************************"
369 "**************************************\n";
370
371 d_SF = Kokkos::create_mirror_view_and_copy( memory_space(), SF );
372 d_SFscaling =
373 Kokkos::create_mirror_view_and_copy( memory_space(), SFscaling );
374 d_SFGmemberlist =
375 Kokkos::create_mirror_view_and_copy( memory_space(), SFGmemberlist );
376
377 return;
378}
379
380template <class t_device>
382{
383 log << "\n";
384 log << "*** SETUP: SYMMETRY FUNCTION GROUPS *****"
385 "**************************************\n";
386 log << "\n";
387
388 log << "Abbreviations:\n";
389 log << "--------------\n";
390 log << "ind .... Symmetry function group index.\n";
391 log << "ec ..... Central atom element.\n";
392 log << "ty ..... Symmetry function type.\n";
393 log << "e1 ..... Neighbor 1 element.\n";
394 log << "e2 ..... Neighbor 2 element.\n";
395 log << "eta .... Gaussian width eta.\n";
396 log << "rs ..... Shift distance of Gaussian.\n";
397 log << "la ..... Angle prefactor lambda.\n";
398 log << "zeta ... Angle term exponent zeta.\n";
399 log << "rc ..... Cutoff radius.\n";
400 log << "ct ..... Cutoff type.\n";
401 log << "ca ..... Cutoff alpha.\n";
402 log << "ln ..... Line number in settings file.\n";
403 log << "mi ..... Member index.\n";
404 log << "sfi .... Symmetry function index.\n";
405 log << "e ...... Recalculate exponential term.\n";
406 log << "\n";
407
408 h_numSFGperElem =
409 h_t_int( "Mode::numSymmetryFunctionGroupsPerElement", numElements );
410
411 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
412 ++it )
413 {
414 int attype = it->getIndex();
415 it->setupSymmetryFunctionGroups( SF, SFGmemberlist, attype,
416 h_numSFperElem, h_numSFGperElem,
417 maxSFperElem );
418 log << strpr( "Short range atomic symmetry function groups "
419 "element %2s :\n",
420 it->getSymbol().c_str() );
421 log << "-----------------------------------------"
422 "--------------------------------------\n";
423 log << " ind ec ty e1 e2 eta rs la "
424 "zeta rc ct ca ln mi sfi e\n";
425 log << "-----------------------------------------"
426 "--------------------------------------\n";
427 log << it->infoSymmetryFunctionGroups( SF, SFGmemberlist, attype,
428 h_numSFGperElem );
429 log << "-----------------------------------------"
430 "--------------------------------------\n";
431 }
432
433 log << "*****************************************"
434 "**************************************\n";
435
436 numSFGperElem =
437 Kokkos::create_mirror_view_and_copy( memory_space(), h_numSFGperElem );
438
439 return;
440}
441
442template <class t_device>
444{
445 log << "\n";
446 log << "*** SETUP: NEURAL NETWORKS **************"
447 "**************************************\n";
448 log << "\n";
449
450 numLayers = 2 + atoi( settings["global_hidden_layers_short"].c_str() );
451 numHiddenLayers = numLayers - 2;
452
453 h_numNeuronsPerLayer = h_t_int( "Mode::numNeuronsPerLayer", numLayers );
454 h_AF = h_t_int( "Mode::ActivationFunctions", numLayers );
455
456 vector<string> numNeuronsPerHiddenLayer =
457 split( reduce( settings["global_nodes_short"] ) );
458 vector<string> activationFunctions =
459 split( reduce( settings["global_activation_short"] ) );
460
461 for ( int i = 0; i < numLayers; i++ )
462 {
463 if ( i == 0 )
464 h_AF( i ) = 0;
465 else if ( i == numLayers - 1 )
466 {
467 h_numNeuronsPerLayer( i ) = 1;
468 h_AF( i ) = 0;
469 }
470 else
471 {
472 h_numNeuronsPerLayer( i ) =
473 atoi( numNeuronsPerHiddenLayer.at( i - 1 ).c_str() );
474 h_AF( i ) = 1; // TODO: hardcoded atoi(activationFunctions.at(i-1));
475 }
476 }
477
478 // TODO: add normalization of neurons
479 bool normalizeNeurons = settings.keywordExists( "normalize_nodes" );
480 log << strpr( "Normalize neurons (all elements): %d\n",
481 (int)normalizeNeurons );
482 log << "-----------------------------------------"
483 "--------------------------------------\n";
484
485 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
486 ++it )
487 {
488 int attype = it->getIndex();
489 h_numNeuronsPerLayer( 0 ) =
490 it->numSymmetryFunctions( attype, h_numSFperElem );
491 log << strpr( "Atomic short range NN for "
492 "element %2s :\n",
493 it->getSymbol().c_str() );
494
495 int numWeights = 0, numBiases = 0, numConnections = 0;
496 for ( int j = 1; j < numLayers; ++j )
497 {
498 numWeights +=
499 h_numNeuronsPerLayer( j - 1 ) * h_numNeuronsPerLayer( j );
500 numBiases += h_numNeuronsPerLayer( j );
501 }
502 numConnections = numWeights + numBiases;
503 log << strpr( "Number of weights : %6zu\n", numWeights );
504 log << strpr( "Number of biases : %6zu\n", numBiases );
505 log << strpr( "Number of connections: %6zu\n", numConnections );
506 log << strpr( "Architecture " );
507 for ( int j = 0; j < numLayers; ++j )
508 log << strpr( " %4d", h_numNeuronsPerLayer( j ) );
509
510 log << "\n-----------------------------------------"
511 "--------------------------------------\n";
512 }
513
514 // initialize Views
515 maxNeurons = 0;
516 for ( int j = 0; j < numLayers; ++j )
517 maxNeurons = max( maxNeurons, h_numNeuronsPerLayer( j ) );
518
519 h_bias = t_bias( "Mode::biases", numElements, numLayers, maxNeurons );
520 h_weights = t_weights( "Mode::weights", numElements, numLayers,
521 maxNeurons, maxNeurons );
522
523 log << "*****************************************"
524 "**************************************\n";
525
526 return;
527}
528
529template <class t_device>
530void ModeCabana<t_device>::setupNeuralNetworkWeights( string const &fileNameFormat )
531{
532 log << "\n";
533 log << "*** SETUP: NEURAL NETWORK WEIGHTS *******"
534 "**************************************\n";
535 log << "\n";
536
537 log << strpr( "Weight file name format: %s\n",
538 fileNameFormat.c_str() );
539 int count = 0;
540 int AN = 0;
541 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
542 ++it )
543 {
544 const char *estring = elementStrings[count].c_str();
545 for ( size_t i = 0; i < knownElements.size(); ++i )
546 {
547 if ( strcmp( knownElements[i].c_str(), estring ) == 0 )
548 {
549 AN = i + 1;
550 break;
551 }
552 }
553
554 string fileName = strpr( fileNameFormat.c_str(), AN );
555 log << strpr( "Weight file for element %2s: %s\n",
556 elementStrings[count].c_str(), fileName.c_str() );
557 ifstream file;
558 file.open( fileName.c_str() );
559 if ( !file.is_open() )
560 {
561 throw runtime_error( "ERROR: Could not open file: \"" + fileName +
562 "\".\n" );
563 }
564 string line;
565 int attype = it->getIndex();
566 int layer, start, end;
567 while ( getline( file, line ) )
568 {
569 if ( line.at( 0 ) != '#' )
570 {
571 vector<string> splitLine = split( reduce( line ) );
572 if ( strcmp( splitLine.at( 1 ).c_str(), "a" ) == 0 )
573 {
574 layer = atoi( splitLine.at( 3 ).c_str() );
575 start = atoi( splitLine.at( 4 ).c_str() ) - 1;
576 end = atoi( splitLine.at( 6 ).c_str() ) - 1;
577 h_weights( attype, layer, end, start ) =
578 atof( splitLine.at( 0 ).c_str() );
579 }
580 else if ( strcmp( splitLine.at( 1 ).c_str(), "b" ) == 0 )
581 {
582 layer = atoi( splitLine.at( 3 ).c_str() ) - 1;
583 start = atoi( splitLine.at( 4 ).c_str() ) - 1;
584 h_bias( attype, layer, start ) =
585 atof( splitLine.at( 0 ).c_str() );
586 }
587 }
588 }
589 file.close();
590 count += 1;
591 }
592 log << "*****************************************"
593 "**************************************\n";
594
595 bias = Kokkos::create_mirror_view_and_copy( memory_space(), h_bias );
596 weights = Kokkos::create_mirror_view_and_copy( memory_space(), h_weights );
597 AF = Kokkos::create_mirror_view_and_copy( memory_space(), h_AF );
598 numNeuronsPerLayer = Kokkos::create_mirror_view_and_copy(
599 memory_space(), h_numNeuronsPerLayer );
600
601 return;
602}
603
604template <class t_device>
605template <class t_slice_x, class t_slice_type, class t_slice_G,
606 class t_neigh_list, class t_neigh_parallel, class t_angle_parallel>
608 t_slice_x x, t_slice_type type, t_slice_G G, t_neigh_list neigh_list,
609 int N_local, t_neigh_parallel neigh_op_tag, t_angle_parallel angle_op_tag )
610{
611 Cabana::deep_copy( G, 0.0 );
612
613 Kokkos::RangePolicy<exe_space> policy( 0, N_local );
614
615 // Create local copies for lambda
616 auto numSFGperElem_ = numSFGperElem;
617 auto SFGmemberlist_ = d_SFGmemberlist;
618 auto SF_ = d_SF;
619 auto SFscaling_ = d_SFscaling;
620 auto maxSFperElem_ = maxSFperElem;
621 auto convLength_ = convLength;
622 auto cutoffType_ = cutoffType;
623 auto cutoffAlpha_ = cutoffAlpha;
624
625 auto calc_radial_symm_op = KOKKOS_LAMBDA( const int i, const int j )
626 {
627 double pfcij = 0.0;
628 double pdfcij = 0.0;
629 double eta, rs;
630 size_t nej;
631 int memberindex, globalIndex;
632 double rij, r2ij;
633 T_F_FLOAT dxij, dyij, dzij;
634
635 int attype = type( i );
636 for ( int groupIndex = 0; groupIndex < numSFGperElem_( attype );
637 ++groupIndex )
638 {
639 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
640 2 )
641 {
642 size_t memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
643 size_t e1 = SF_( attype, memberindex0, 2 );
644 double rc = SF_( attype, memberindex0, 7 );
645 size_t size =
646 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
647
648 nej = type( j );
649 dxij = ( x( i, 0 ) - x( j, 0 ) ) * CFLENGTH * convLength_;
650 dyij = ( x( i, 1 ) - x( j, 1 ) ) * CFLENGTH * convLength_;
651 dzij = ( x( i, 2 ) - x( j, 2 ) ) * CFLENGTH * convLength_;
652 r2ij = dxij * dxij + dyij * dyij + dzij * dzij;
653 rij = sqrt( r2ij );
654 if ( e1 == nej && rij < rc )
655 {
656 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
657 rij, rc, false );
658 for ( size_t k = 0; k < size; ++k )
659 {
660 memberindex = SFGmemberlist_( attype, groupIndex, k );
661 globalIndex = SF_( attype, memberindex, 14 );
662 eta = SF_( attype, memberindex, 4 );
663 rs = SF_( attype, memberindex, 8 );
664 G( i, globalIndex ) +=
665 exp( -eta * ( rij - rs ) * ( rij - rs ) ) * pfcij;
666 }
667 }
668 }
669 }
670 };
671 Cabana::neighbor_parallel_for(
672 policy, calc_radial_symm_op, neigh_list, Cabana::FirstNeighborsTag(),
673 neigh_op_tag, "Mode::calculateRadialSymmetryFunctionGroups" );
674 Kokkos::fence();
675
676 auto calc_angular_symm_op =
677 KOKKOS_LAMBDA( const int i, const int j, const int k )
678 {
679 double pfcij = 0.0, pdfcij = 0.0;
680 double pfcik = 0.0, pdfcik = 0.0;
681 double pfcjk = 0.0, pdfcjk = 0.0;
682 size_t nej, nek;
683 int memberindex, globalIndex;
684 double rij, r2ij, rik, r2ik, rjk, r2jk;
685 T_F_FLOAT dxij, dyij, dzij, dxik, dyik, dzik, dxjk, dyjk, dzjk;
686 double eta, rs, lambda, zeta;
687
688 int attype = type( i );
689 for ( int groupIndex = 0; groupIndex < numSFGperElem_( attype );
690 ++groupIndex )
691 {
692 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
693 3 )
694 {
695 size_t memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
696 size_t e1 = SF_( attype, memberindex0, 2 );
697 size_t e2 = SF_( attype, memberindex0, 3 );
698 double rc = SF_( attype, memberindex0, 7 );
699 size_t size =
700 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
701
702 nej = type( j );
703 dxij = ( x( i, 0 ) - x( j, 0 ) ) * CFLENGTH * convLength_;
704 dyij = ( x( i, 1 ) - x( j, 1 ) ) * CFLENGTH * convLength_;
705 dzij = ( x( i, 2 ) - x( j, 2 ) ) * CFLENGTH * convLength_;
706 r2ij = dxij * dxij + dyij * dyij + dzij * dzij;
707 rij = sqrt( r2ij );
708 if ( ( e1 == nej || e2 == nej ) && rij < rc )
709 {
710 // Calculate cutoff function and derivative.
711 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
712 rij, rc, false );
713
714 nek = type( k );
715
716 if ( ( e1 == nej && e2 == nek ) ||
717 ( e2 == nej && e1 == nek ) )
718 {
719 dxik =
720 ( x( i, 0 ) - x( k, 0 ) ) * CFLENGTH * convLength_;
721 dyik =
722 ( x( i, 1 ) - x( k, 1 ) ) * CFLENGTH * convLength_;
723 dzik =
724 ( x( i, 2 ) - x( k, 2 ) ) * CFLENGTH * convLength_;
725 r2ik = dxik * dxik + dyik * dyik + dzik * dzik;
726 rik = sqrt( r2ik );
727 if ( rik < rc )
728 {
729 dxjk = dxik - dxij;
730 dyjk = dyik - dyij;
731 dzjk = dzik - dzij;
732 r2jk = dxjk * dxjk + dyjk * dyjk + dzjk * dzjk;
733 if ( r2jk < rc * rc )
734 {
735 // Energy calculation.
736 compute_cutoff( cutoffType_, cutoffAlpha_,
737 pfcik, pdfcik, rik, rc, false );
738
739 rjk = sqrt( r2jk );
740 compute_cutoff( cutoffType_, cutoffAlpha_,
741 pfcjk, pdfcjk, rjk, rc, false );
742
743 double const rinvijik = 1.0 / rij / rik;
744 double const costijk =
745 ( dxij * dxik + dyij * dyik +
746 dzij * dzik ) *
747 rinvijik;
748 double vexp = 0.0, rijs = 0.0, riks = 0.0,
749 rjks = 0.0;
750 for ( size_t l = 0; l < size; ++l )
751 {
752 globalIndex =
753 SF_( attype,
754 SFGmemberlist_( attype,
755 groupIndex, l ),
756 14 );
757 memberindex = SFGmemberlist_(
758 attype, groupIndex, l );
759 eta = SF_( attype, memberindex, 4 );
760 lambda = SF_( attype, memberindex, 5 );
761 zeta = SF_( attype, memberindex, 6 );
762 rs = SF_( attype, memberindex, 8 );
763 if ( rs > 0.0 )
764 {
765 rijs = rij - rs;
766 riks = rik - rs;
767 rjks = rjk - rs;
768 vexp = exp( -eta * ( rijs * rijs +
769 riks * riks +
770 rjks * rjks ) );
771 }
772 else
773 vexp = exp( -eta *
774 ( r2ij + r2ik + r2jk ) );
775 double const plambda =
776 1.0 + lambda * costijk;
777 double fg = vexp;
778 if ( plambda <= 0.0 )
779 fg = 0.0;
780 else
781 fg *= pow( plambda, ( zeta - 1.0 ) );
782 G( i, globalIndex ) +=
783 fg * plambda * pfcij * pfcik * pfcjk;
784 } // l
785 } // rjk <= rc
786 } // rik <= rc
787 } // elem
788 } // rij <= rc
789 }
790 }
791 };
792 Cabana::neighbor_parallel_for(
793 policy, calc_angular_symm_op, neigh_list, Cabana::SecondNeighborsTag(),
794 angle_op_tag, "Mode::calculateAngularSymmetryFunctionGroups" );
795 Kokkos::fence();
796
797 auto scale_symm_op = KOKKOS_LAMBDA( const int i )
798 {
799 int attype = type( i );
800
801 int memberindex0;
802 int memberindex, globalIndex;
803 double raw_value = 0.0;
804 for ( int groupIndex = 0; groupIndex < numSFGperElem_( attype );
805 ++groupIndex )
806 {
807 memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
808
809 size_t size = SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
810 for ( size_t k = 0; k < size; ++k )
811 {
812 globalIndex = SF_(
813 attype, SFGmemberlist_( attype, groupIndex, k ), 14 );
814 memberindex = SFGmemberlist_( attype, groupIndex, k );
815
816 if ( SF_( attype, memberindex0, 1 ) == 2 )
817 raw_value = G( i, globalIndex );
818 else if ( SF_( attype, memberindex0, 1 ) == 3 )
819 raw_value =
820 G( i, globalIndex ) *
821 pow( 2, ( 1 - SF_( attype, memberindex, 6 ) ) );
822
823 G( i, globalIndex ) =
824 scale( attype, raw_value, memberindex, SFscaling_ );
825 }
826 }
827 };
828 Kokkos::parallel_for( "Mode::scaleSymmetryFunctionGroups", policy,
829 scale_symm_op );
830 Kokkos::fence();
831}
832
833template <class t_device>
834template <class t_slice_type, class t_slice_G, class t_slice_dEdG,
835 class t_slice_E>
837 t_slice_type type, t_slice_G G, t_slice_dEdG dEdG, t_slice_E E, int N_local )
838{
839 auto NN = d_t_NN( "Mode::NN", N_local, numLayers, maxNeurons );
840 auto dfdx = d_t_NN( "Mode::dfdx", N_local, numLayers, maxNeurons );
841 auto inner = d_t_NN( "Mode::inner", N_local, numHiddenLayers, maxNeurons );
842 auto outer = d_t_NN( "Mode::outer", N_local, numHiddenLayers, maxNeurons );
843
844 Kokkos::RangePolicy<exe_space> policy( 0, N_local );
845
846 // Create local copies for lambda
847 auto numSFperElem_ = numSFperElem;
848 auto numNeuronsPerLayer_ = numNeuronsPerLayer;
849 auto numLayers_ = numLayers;
850 auto numHiddenLayers_ = numHiddenLayers;
851 auto AF_ = AF;
852 auto weights_ = weights;
853 auto bias_ = bias;
854
855 auto calc_nn_op = KOKKOS_LAMBDA( const int atomindex )
856 {
857 int attype = type( atomindex );
858 // set input layer of NN
859 int layer_0, layer_lminusone;
860 layer_0 = (int)numSFperElem_( attype );
861
862 for ( int k = 0; k < layer_0; ++k )
863 NN( atomindex, 0, k ) = G( atomindex, k );
864 // forward propagation
865 for ( int l = 1; l < numLayers_; l++ )
866 {
867 if ( l == 1 )
868 layer_lminusone = layer_0;
869 else
870 layer_lminusone = numNeuronsPerLayer_( l - 1 );
871 double dtmp;
872 for ( int i = 0; i < numNeuronsPerLayer_( l ); i++ )
873 {
874 dtmp = 0.0;
875 for ( int j = 0; j < layer_lminusone; j++ )
876 dtmp += weights_( attype, l - 1, i, j ) *
877 NN( atomindex, l - 1, j );
878 dtmp += bias_( attype, l - 1, i );
879 if ( AF_( l ) == 0 )
880 {
881 NN( atomindex, l, i ) = dtmp;
882 dfdx( atomindex, l, i ) = 1.0;
883 }
884 else if ( AF_( l ) == 1 )
885 {
886 dtmp = tanh( dtmp );
887 NN( atomindex, l, i ) = dtmp;
888 dfdx( atomindex, l, i ) = 1.0 - dtmp * dtmp;
889 }
890 }
891 }
892
893 E( atomindex ) = NN( atomindex, numLayers_ - 1, 0 );
894
895 // derivative of network w.r.t NN inputs
896 for ( int k = 0; k < numNeuronsPerLayer_( 0 ); k++ )
897 {
898 for ( int i = 0; i < numNeuronsPerLayer_( 1 ); i++ )
899 inner( atomindex, 0, i ) =
900 weights_( attype, 0, i, k ) * dfdx( atomindex, 1, i );
901
902 for ( int l = 1; l < numHiddenLayers_ + 1; l++ )
903 {
904 for ( int i2 = 0; i2 < numNeuronsPerLayer_( l + 1 ); i2++ )
905 {
906 outer( atomindex, l - 1, i2 ) = 0.0;
907
908 for ( int i1 = 0; i1 < numNeuronsPerLayer_( l ); i1++ )
909 outer( atomindex, l - 1, i2 ) +=
910 weights_( attype, l, i2, i1 ) *
911 inner( atomindex, l - 1, i1 );
912 outer( atomindex, l - 1, i2 ) *=
913 dfdx( atomindex, l + 1, i2 );
914
915 if ( l < numHiddenLayers_ )
916 inner( atomindex, l, i2 ) =
917 outer( atomindex, l - 1, i2 );
918 }
919 }
920 dEdG( atomindex, k ) = outer( atomindex, numHiddenLayers_ - 1, 0 );
921 }
922 };
923 Kokkos::parallel_for( "Mode::calculateAtomicNeuralNetworks", policy,
924 calc_nn_op );
925 Kokkos::fence();
926}
927
928template <class t_device>
929template <class t_slice_x, class t_slice_f, class t_slice_type,
930 class t_slice_dEdG, class t_neigh_list, class t_neigh_parallel,
931 class t_angle_parallel>
933 t_slice_x x, t_slice_f f_a, t_slice_type type, t_slice_dEdG dEdG,
934 t_neigh_list neigh_list, int N_local, t_neigh_parallel neigh_op_tag,
935 t_angle_parallel angle_op_tag )
936{
937 double convForce_ = convLength / convEnergy;
938
939 Kokkos::RangePolicy<exe_space> policy( 0, N_local );
940
941 // Create local copies for lambda
942 auto numSFGperElem_ = numSFGperElem;
943 auto SFGmemberlist_ = d_SFGmemberlist;
944 auto SF_ = d_SF;
945 auto SFscaling_ = d_SFscaling;
946 auto maxSFperElem_ = maxSFperElem;
947 auto convLength_ = convLength;
948 auto cutoffType_ = cutoffType;
949 auto cutoffAlpha_ = cutoffAlpha;
950
951 auto calc_radial_force_op = KOKKOS_LAMBDA( const int i, const int j )
952 {
953 double pfcij = 0.0;
954 double pdfcij = 0.0;
955 double rij, r2ij;
956 T_F_FLOAT dxij, dyij, dzij;
957 double eta, rs;
958 int memberindex, globalIndex;
959
960 int attype = type( i );
961
962 for ( int groupIndex = 0; groupIndex < numSFGperElem_( attype );
963 ++groupIndex )
964 {
965 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
966 2 )
967 {
968 size_t memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
969 size_t e1 = SF_( attype, memberindex0, 2 );
970 double rc = SF_( attype, memberindex0, 7 );
971 size_t size =
972 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
973
974 size_t nej = type( j );
975 dxij = ( x( i, 0 ) - x( j, 0 ) ) * CFLENGTH * convLength_;
976 dyij = ( x( i, 1 ) - x( j, 1 ) ) * CFLENGTH * convLength_;
977 dzij = ( x( i, 2 ) - x( j, 2 ) ) * CFLENGTH * convLength_;
978 r2ij = dxij * dxij + dyij * dyij + dzij * dzij;
979 rij = sqrt( r2ij );
980 if ( e1 == nej && rij < rc )
981 {
982 // Energy calculation.
983 // Calculate cutoff function and derivative.
984 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
985 rij, rc, true );
986 for ( size_t k = 0; k < size; ++k )
987 {
988 globalIndex = SF_(
989 attype, SFGmemberlist_( attype, groupIndex, k ),
990 14 );
991 memberindex = SFGmemberlist_( attype, groupIndex, k );
992 eta = SF_( attype, memberindex, 4 );
993 rs = SF_( attype, memberindex, 8 );
994 double pexp = exp( -eta * ( rij - rs ) * ( rij - rs ) );
995 // Force calculation.
996 double const p1 =
997 SFscaling_( attype, memberindex, 6 ) *
998 ( pdfcij - 2.0 * eta * ( rij - rs ) * pfcij ) *
999 pexp / rij;
1000 f_a( i, 0 ) -= ( dEdG( i, globalIndex ) *
1001 ( p1 * dxij ) * CFFORCE * convForce_ );
1002 f_a( i, 1 ) -= ( dEdG( i, globalIndex ) *
1003 ( p1 * dyij ) * CFFORCE * convForce_ );
1004 f_a( i, 2 ) -= ( dEdG( i, globalIndex ) *
1005 ( p1 * dzij ) * CFFORCE * convForce_ );
1006
1007 f_a( j, 0 ) += ( dEdG( i, globalIndex ) *
1008 ( p1 * dxij ) * CFFORCE * convForce_ );
1009 f_a( j, 1 ) += ( dEdG( i, globalIndex ) *
1010 ( p1 * dyij ) * CFFORCE * convForce_ );
1011 f_a( j, 2 ) += ( dEdG( i, globalIndex ) *
1012 ( p1 * dzij ) * CFFORCE * convForce_ );
1013 }
1014 }
1015 }
1016 }
1017 };
1018 Cabana::neighbor_parallel_for( policy, calc_radial_force_op, neigh_list,
1019 Cabana::FirstNeighborsTag(), neigh_op_tag,
1020 "Mode::calculateRadialForces" );
1021 Kokkos::fence();
1022
1023 auto calc_angular_force_op =
1024 KOKKOS_LAMBDA( const int i, const int j, const int k )
1025 {
1026 double pfcij = 0.0;
1027 double pdfcij = 0.0;
1028 double pfcik, pdfcik, pfcjk, pdfcjk;
1029 size_t nej, nek;
1030 double rij, r2ij, rik, r2ik, rjk, r2jk;
1031 T_F_FLOAT dxij, dyij, dzij, dxik, dyik, dzik, dxjk, dyjk, dzjk;
1032 double eta, rs, lambda, zeta;
1033 int memberindex, globalIndex;
1034
1035 int attype = type( i );
1036 for ( int groupIndex = 0; groupIndex < numSFGperElem_( attype );
1037 ++groupIndex )
1038 {
1039 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
1040 3 )
1041 {
1042 size_t memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
1043 size_t e1 = SF_( attype, memberindex0, 2 );
1044 size_t e2 = SF_( attype, memberindex0, 3 );
1045 double rc = SF_( attype, memberindex0, 7 );
1046 size_t size =
1047 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
1048
1049 nej = type( j );
1050 dxij = ( x( i, 0 ) - x( j, 0 ) ) * CFLENGTH * convLength_;
1051 dyij = ( x( i, 1 ) - x( j, 1 ) ) * CFLENGTH * convLength_;
1052 dzij = ( x( i, 2 ) - x( j, 2 ) ) * CFLENGTH * convLength_;
1053 r2ij = dxij * dxij + dyij * dyij + dzij * dzij;
1054 rij = sqrt( r2ij );
1055 if ( ( e1 == nej || e2 == nej ) && rij < rc )
1056 {
1057 // Calculate cutoff function and derivative.
1058 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
1059 rij, rc, true );
1060
1061 nek = type( k );
1062 if ( ( e1 == nej && e2 == nek ) ||
1063 ( e2 == nej && e1 == nek ) )
1064 {
1065 dxik =
1066 ( x( i, 0 ) - x( k, 0 ) ) * CFLENGTH * convLength_;
1067 dyik =
1068 ( x( i, 1 ) - x( k, 1 ) ) * CFLENGTH * convLength_;
1069 dzik =
1070 ( x( i, 2 ) - x( k, 2 ) ) * CFLENGTH * convLength_;
1071 r2ik = dxik * dxik + dyik * dyik + dzik * dzik;
1072 rik = sqrt( r2ik );
1073 if ( rik < rc )
1074 {
1075 dxjk = dxik - dxij;
1076 dyjk = dyik - dyij;
1077 dzjk = dzik - dzij;
1078 r2jk = dxjk * dxjk + dyjk * dyjk + dzjk * dzjk;
1079 if ( r2jk < rc * rc )
1080 {
1081 // Energy calculation.
1082 compute_cutoff( cutoffType_, cutoffAlpha_,
1083 pfcik, pdfcik, rik, rc, true );
1084 rjk = sqrt( r2jk );
1085
1086 compute_cutoff( cutoffType_, cutoffAlpha_,
1087 pfcjk, pdfcjk, rjk, rc, true );
1088
1089 double const rinvijik = 1.0 / rij / rik;
1090 double const costijk =
1091 ( dxij * dxik + dyij * dyik +
1092 dzij * dzik ) *
1093 rinvijik;
1094 double const pfc = pfcij * pfcik * pfcjk;
1095 double const r2sum = r2ij + r2ik + r2jk;
1096 double const pr1 = pfcik * pfcjk * pdfcij / rij;
1097 double const pr2 = pfcij * pfcjk * pdfcik / rik;
1098 double const pr3 = pfcij * pfcik * pdfcjk / rjk;
1099 double vexp = 0.0, rijs = 0.0, riks = 0.0,
1100 rjks = 0.0;
1101 for ( size_t l = 0; l < size; ++l )
1102 {
1103 globalIndex =
1104 SF_( attype,
1105 SFGmemberlist_( attype,
1106 groupIndex, l ),
1107 14 );
1108 memberindex = SFGmemberlist_(
1109 attype, groupIndex, l );
1110 rs = SF_( attype, memberindex, 8 );
1111 eta = SF_( attype, memberindex, 4 );
1112 lambda = SF_( attype, memberindex, 5 );
1113 zeta = SF_( attype, memberindex, 6 );
1114 if ( rs > 0.0 )
1115 {
1116 rijs = rij - rs;
1117 riks = rik - rs;
1118 rjks = rjk - rs;
1119 vexp = exp( -eta * ( rijs * rijs +
1120 riks * riks +
1121 rjks * rjks ) );
1122 }
1123 else
1124 vexp = exp( -eta * r2sum );
1125
1126 double const plambda =
1127 1.0 + lambda * costijk;
1128 double fg = vexp;
1129 if ( plambda <= 0.0 )
1130 fg = 0.0;
1131 else
1132 fg *= pow( plambda, ( zeta - 1.0 ) );
1133
1134 fg *= pow( 2, ( 1 - zeta ) ) *
1135 SFscaling_( attype, memberindex, 6 );
1136 double const pfczl = pfc * zeta * lambda;
1137 double factorDeriv =
1138 2.0 * eta / zeta / lambda;
1139 double const p2etapl =
1140 plambda * factorDeriv;
1141 double p1, p2, p3;
1142 if ( rs > 0.0 )
1143 {
1144 p1 = fg *
1145 ( pfczl *
1146 ( rinvijik - costijk / r2ij -
1147 p2etapl * rijs / rij ) +
1148 pr1 * plambda );
1149 p2 = fg *
1150 ( pfczl *
1151 ( rinvijik - costijk / r2ik -
1152 p2etapl * riks / rik ) +
1153 pr2 * plambda );
1154 p3 =
1155 fg *
1156 ( pfczl * ( rinvijik +
1157 p2etapl * rjks / rjk ) -
1158 pr3 * plambda );
1159 }
1160 else
1161 {
1162 p1 = fg * ( pfczl * ( rinvijik -
1163 costijk / r2ij -
1164 p2etapl ) +
1165 pr1 * plambda );
1166 p2 = fg * ( pfczl * ( rinvijik -
1167 costijk / r2ik -
1168 p2etapl ) +
1169 pr2 * plambda );
1170 p3 = fg *
1171 ( pfczl * ( rinvijik + p2etapl ) -
1172 pr3 * plambda );
1173 }
1174 f_a( i, 0 ) -= ( dEdG( i, globalIndex ) *
1175 ( p1 * dxij + p2 * dxik ) *
1176 CFFORCE * convForce_ );
1177 f_a( i, 1 ) -= ( dEdG( i, globalIndex ) *
1178 ( p1 * dyij + p2 * dyik ) *
1179 CFFORCE * convForce_ );
1180 f_a( i, 2 ) -= ( dEdG( i, globalIndex ) *
1181 ( p1 * dzij + p2 * dzik ) *
1182 CFFORCE * convForce_ );
1183
1184 f_a( j, 0 ) += ( dEdG( i, globalIndex ) *
1185 ( p1 * dxij + p3 * dxjk ) *
1186 CFFORCE * convForce_ );
1187 f_a( j, 1 ) += ( dEdG( i, globalIndex ) *
1188 ( p1 * dyij + p3 * dyjk ) *
1189 CFFORCE * convForce_ );
1190 f_a( j, 2 ) += ( dEdG( i, globalIndex ) *
1191 ( p1 * dzij + p3 * dzjk ) *
1192 CFFORCE * convForce_ );
1193
1194 f_a( k, 0 ) += ( dEdG( i, globalIndex ) *
1195 ( p2 * dxik - p3 * dxjk ) *
1196 CFFORCE * convForce_ );
1197 f_a( k, 1 ) += ( dEdG( i, globalIndex ) *
1198 ( p2 * dyik - p3 * dyjk ) *
1199 CFFORCE * convForce_ );
1200 f_a( k, 2 ) += ( dEdG( i, globalIndex ) *
1201 ( p2 * dzik - p3 * dzjk ) *
1202 CFFORCE * convForce_ );
1203 } // l
1204 } // rjk <= rc
1205 } // rik <= rc
1206 } // elem
1207 } // rij <= rc
1208 }
1209 }
1210 };
1211 Cabana::neighbor_parallel_for( policy, calc_angular_force_op, neigh_list,
1212 Cabana::SecondNeighborsTag(), angle_op_tag,
1213 "Mode::calculateAngularForces" );
1214 Kokkos::fence();
1215
1216 return;
1217}
1218
1219}
Derived Cabana class for element-specific data.
Definition: ElementCabana.h:36
void calculateSymmetryFunctionGroups(t_slice_x x, t_slice_type type, t_slice_G G, t_neigh_list neigh_list, int N_local, t_neigh_parallel neigh_op, t_angle_parallel angle_op)
Calculate all symmetry function groups for all atoms in given structure.
void setupSymmetryFunctions() override
Set up all symmetry functions.
void setupSymmetryFunctionGroups() override
Set up symmetry function groups.
void setupNeuralNetworkWeights(std::string const &fileNameFormat="weights.%03zu.data") override
Set up neural network weights from files.
void setupElementMap() override
Set up the element map.
Kokkos::View< T_FLOAT **[15], layout, host_space > t_SF
Definition: ModeCabana.h:67
void calculateForces(t_slice_x x, t_slice_f f, t_slice_type type, t_slice_dEdG dEdG, t_neigh_list neigh_list, int N_local, t_neigh_parallel neigh_op, t_angle_parallel angle_op)
Calculate forces for all atoms in given structure.
Kokkos::View< T_FLOAT ***, layout, host_space > t_bias
Definition: ModeCabana.h:75
typename device_type::memory_space memory_space
Definition: ModeCabana.h:55
Kokkos::View< T_INT *, layout, host_space > h_t_int
Definition: ModeCabana.h:63
Kokkos::View< T_INT ***, layout, host_space > t_SFGmemberlist
Definition: ModeCabana.h:71
Kokkos::View< T_FLOAT ****, layout, host_space > t_weights
Definition: ModeCabana.h:77
Kokkos::View< T_FLOAT ***, memory_space > d_t_NN
Definition: ModeCabana.h:78
Kokkos::View< T_V_FLOAT *, layout, host_space > h_t_mass
Definition: ModeCabana.h:61
Kokkos::View< T_FLOAT **[8], layout, host_space > t_SFscaling
Definition: ModeCabana.h:69
void calculateAtomicNeuralNetworks(t_slice_type type, t_slice_G G, t_slice_dEdG dEdG, t_slice_E E, int N_local)
Calculate atomic neural networks for all atoms in given structure.
void setupSymmetryFunctionScaling(std::string const &fileName="scaling.data") override
Set up symmetry function scaling from file.
void setupElements() override
Set up all Element instances.
void setupNeuralNetwork() override
Set up neural networks for all elements.
Definition: Atom.h:29
string strpr(const char *format,...)
String version of printf function.
Definition: utility.cpp:90
vector< string > split(string const &input, char delimiter)
Split string at each delimiter.
Definition: utility.cpp:33
string reduce(string const &line, string const &whitespace, string const &fill)
Replace multiple whitespaces with fill.
Definition: utility.cpp:60
constexpr double CFLENGTH
Definition: typesCabana.h:21
constexpr double CFFORCE
Definition: typesCabana.h:23
@ ST_CENTER
Definition: typesCabana.h:29
@ ST_SCALE
Definition: typesCabana.h:28
@ ST_SCALECENTER
Definition: typesCabana.h:30
@ ST_NONE
Definition: typesCabana.h:27
@ ST_SCALESIGMA
Definition: typesCabana.h:31