33template <
class t_device>
37 log <<
"*** SETUP: ELEMENT MAP ******************"
38 "**************************************\n";
41 elementStrings =
split(
reduce( settings[
"elements"] ) );
43 log <<
strpr(
"Number of element strings found: %d\n",
44 elementStrings.size() );
45 for (
size_t i = 0; i < elementStrings.size(); ++i )
47 log <<
strpr(
"Element %2zu: %2s\n", i,
48 elementStrings[i].c_str() );
51 numElements = elementStrings.size();
53 log <<
"*****************************************"
54 "**************************************\n";
59template <
class t_device>
63 log <<
"*** SETUP: ELEMENTS *********************"
64 "**************************************\n";
67 numElements = (size_t)atoi( settings[
"number_of_elements"].c_str() );
69 h_t_mass(
"Mode::atomicEnergyOffset", numElements );
70 if ( numElements != elementStrings.size() )
72 throw runtime_error(
"ERROR: Inconsistent number of elements.\n" );
74 log <<
strpr(
"Number of elements is consistent: %zu\n", numElements );
76 for (
size_t i = 0; i < numElements; ++i )
81 if ( settings.keywordExists(
"atom_energy" ) )
83 Settings::KeyRange r = settings.getValues(
"atom_energy" );
84 for ( Settings::KeyMap::const_iterator it = r.first;
85 it != r.second; ++it )
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 )
91 if ( strcmp( elementStrings[i].c_str(), estring ) == 0 )
92 atomicEnergyOffset( i ) = atof( args.at( 1 ).c_str() );
97 log <<
"Atomic energy offsets per element:\n";
98 for (
size_t i = 0; i < elementStrings.size(); ++i )
100 log <<
strpr(
"Element %2zu: %16.8E\n", i,
101 atomicEnergyOffset( i ) );
104 log <<
"Energy offsets are automatically subtracted from reference "
106 log <<
"*****************************************"
107 "**************************************\n";
112template <
class t_device>
117 h_t_int(
"Mode::numSymmetryFunctionsPerElement", numElements );
119 log <<
"*** SETUP: SYMMETRY FUNCTIONS ***********"
120 "**************************************\n";
124 Settings::KeyRange r = settings.getValues(
"symfunction_short" );
125 for ( Settings::KeyMap::const_iterator it = r.first; it != r.second;
128 vector<string> args =
split(
reduce( it->second.first ) );
130 const char *estring = args.at( 0 ).c_str();
131 for (
size_t i = 0; i < elementStrings.size(); ++i )
133 if ( strcmp( elementStrings[i].c_str(), estring ) == 0 )
136 h_numSFperElem( type )++;
138 if ( h_numSFperElem( type ) > maxSFperElem )
139 maxSFperElem = h_numSFperElem( type );
141 Kokkos::deep_copy( h_numSFperElem, 0 );
145 SF =
t_SF(
"SymmetryFunctions", numElements, maxSFperElem );
146 SFscaling =
t_SFscaling(
"SFscaling", numElements, maxSFperElem );
149 maxSFperElem + 1, maxSFperElem + 1 );
151 r = settings.getValues(
"symfunction_short" );
152 for ( Settings::KeyMap::const_iterator it = r.first; it != r.second;
155 vector<string> args =
split(
reduce( it->second.first ) );
157 const char *estring = args.at( 0 ).c_str();
158 for (
size_t i = 0; i < elementStrings.size(); ++i )
160 if ( strcmp( elementStrings[i].c_str(), estring ) == 0 )
163 elements.at( type ).addSymmetryFunction( it->second.first,
164 elementStrings, type, SF,
165 convLength, h_numSFperElem );
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";
184 maxCutoffRadius = 0.0;
186 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
189 int attype = it->getIndex();
190 it->sortSymmetryFunctions( SF, h_numSFperElem, attype );
192 max( it->getMaxCutoffRadius( SF, attype, h_numSFperElem ),
194 it->setCutoffFunction( cutoffType, cutoffAlpha, SF, attype,
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";
209 minNeighbors.resize( numElements, 0 );
210 minCutoffRadius.resize( numElements, maxCutoffRadius );
211 for (
size_t i = 0; i < numElements; ++i )
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 );
223 log <<
strpr(
"Maximum cutoff radius (global) : %f\n",
224 maxCutoffRadius / convLength );
226 log <<
"*****************************************"
227 "**************************************\n";
230 Kokkos::create_mirror_view_and_copy(
memory_space(), h_numSFperElem );
236template <
class t_device>
240 log <<
"*** SETUP: SYMMETRY FUNCTION SCALING ****"
241 "**************************************\n";
244 log <<
"Equal scaling type for all symmetry functions:\n";
245 if ( ( settings.keywordExists(
"scale_symmetry_functions" ) ) &&
246 ( !settings.keywordExists(
"center_symmetry_functions" ) ) )
249 log <<
strpr(
"Scaling type::ST_SCALE (%d)\n", scalingType );
250 log <<
"Gs = Smin + (Smax - Smin) * (G - Gmin) / (Gmax - Gmin)\n";
252 else if ( ( !settings.keywordExists(
"scale_symmetry_functions" ) ) &&
253 ( settings.keywordExists(
"center_symmetry_functions" ) ) )
256 log <<
strpr(
"Scaling type::ST_CENTER (%d)\n", scalingType );
257 log <<
"Gs = G - Gmean\n";
259 else if ( ( settings.keywordExists(
"scale_symmetry_functions" ) ) &&
260 ( settings.keywordExists(
"center_symmetry_functions" ) ) )
263 log <<
strpr(
"Scaling type::ST_SCALECENTER (%d)\n", scalingType );
264 log <<
"Gs = Smin + (Smax - Smin) * (G - Gmean) / (Gmax - Gmin)\n";
266 else if ( settings.keywordExists(
"scale_symmetry_functions_sigma" ) )
269 log <<
strpr(
"Scaling type::ST_SCALESIGMA (%d)\n", scalingType );
270 log <<
"Gs = Smin + (Smax - Smin) * (G - Gmean) / Gsigma\n";
275 log <<
strpr(
"Scaling type::ST_NONE (%d)\n", scalingType );
277 log <<
"WARNING: No symmetry function scaling!\n";
285 if ( settings.keywordExists(
"scale_min_short" ) )
287 Smin = atof( settings[
"scale_min_short"].c_str() );
291 log <<
"WARNING: Keyword \"scale_min_short\" not found.\n";
292 log <<
" Default value for Smin = 0.0.\n";
296 if ( settings.keywordExists(
"scale_max_short" ) )
298 Smax = atof( settings[
"scale_max_short"].c_str() );
302 log <<
"WARNING: Keyword \"scale_max_short\" not found.\n";
303 log <<
" Default value for Smax = 1.0.\n";
307 log <<
strpr(
"Smin = %f\n", Smin );
308 log <<
strpr(
"Smax = %f\n", Smax );
311 log <<
strpr(
"Symmetry function scaling statistics from file: %s\n",
313 log <<
"-----------------------------------------"
314 "--------------------------------------\n";
316 file.open( fileName.c_str() );
317 if ( !file.is_open() )
319 throw runtime_error(
"ERROR: Could not open file: \"" + fileName +
323 vector<string> lines;
324 while ( getline( file, line ) )
326 if ( line.at( 0 ) !=
'#' )
327 lines.push_back( line );
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";
344 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
347 int attype = it->getIndex();
348 it->setScaling( scalingType, lines, Smin, Smax, SF, SFscaling, attype,
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 "
357 log <<
"-----------------------------------------"
358 "--------------------------------------\n";
359 log << it->infoSymmetryFunctionScaling( scalingType, SF, SFscaling,
360 attype, h_numSFperElem );
361 log <<
"-----------------------------------------"
362 "--------------------------------------\n";
363 lines.erase( lines.begin(),
365 it->numSymmetryFunctions( attype, h_numSFperElem ) );
368 log <<
"*****************************************"
369 "**************************************\n";
371 d_SF = Kokkos::create_mirror_view_and_copy(
memory_space(), SF );
373 Kokkos::create_mirror_view_and_copy(
memory_space(), SFscaling );
375 Kokkos::create_mirror_view_and_copy(
memory_space(), SFGmemberlist );
380template <
class t_device>
384 log <<
"*** SETUP: SYMMETRY FUNCTION GROUPS *****"
385 "**************************************\n";
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";
409 h_t_int(
"Mode::numSymmetryFunctionGroupsPerElement", numElements );
411 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
414 int attype = it->getIndex();
415 it->setupSymmetryFunctionGroups( SF, SFGmemberlist, attype,
416 h_numSFperElem, h_numSFGperElem,
418 log <<
strpr(
"Short range atomic symmetry function groups "
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,
429 log <<
"-----------------------------------------"
430 "--------------------------------------\n";
433 log <<
"*****************************************"
434 "**************************************\n";
437 Kokkos::create_mirror_view_and_copy(
memory_space(), h_numSFGperElem );
442template <
class t_device>
446 log <<
"*** SETUP: NEURAL NETWORKS **************"
447 "**************************************\n";
450 numLayers = 2 + atoi( settings[
"global_hidden_layers_short"].c_str() );
451 numHiddenLayers = numLayers - 2;
453 h_numNeuronsPerLayer =
h_t_int(
"Mode::numNeuronsPerLayer", numLayers );
454 h_AF =
h_t_int(
"Mode::ActivationFunctions", numLayers );
456 vector<string> numNeuronsPerHiddenLayer =
458 vector<string> activationFunctions =
459 split(
reduce( settings[
"global_activation_short"] ) );
461 for (
int i = 0; i < numLayers; i++ )
465 else if ( i == numLayers - 1 )
467 h_numNeuronsPerLayer( i ) = 1;
472 h_numNeuronsPerLayer( i ) =
473 atoi( numNeuronsPerHiddenLayer.at( i - 1 ).c_str() );
479 bool normalizeNeurons = settings.keywordExists(
"normalize_nodes" );
480 log <<
strpr(
"Normalize neurons (all elements): %d\n",
481 (
int)normalizeNeurons );
482 log <<
"-----------------------------------------"
483 "--------------------------------------\n";
485 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
488 int attype = it->getIndex();
489 h_numNeuronsPerLayer( 0 ) =
490 it->numSymmetryFunctions( attype, h_numSFperElem );
491 log <<
strpr(
"Atomic short range NN for "
493 it->getSymbol().c_str() );
495 int numWeights = 0, numBiases = 0, numConnections = 0;
496 for (
int j = 1; j < numLayers; ++j )
499 h_numNeuronsPerLayer( j - 1 ) * h_numNeuronsPerLayer( j );
500 numBiases += h_numNeuronsPerLayer( j );
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 ) );
510 log <<
"\n-----------------------------------------"
511 "--------------------------------------\n";
516 for (
int j = 0; j < numLayers; ++j )
517 maxNeurons = max( maxNeurons, h_numNeuronsPerLayer( j ) );
519 h_bias =
t_bias(
"Mode::biases", numElements, numLayers, maxNeurons );
520 h_weights =
t_weights(
"Mode::weights", numElements, numLayers,
521 maxNeurons, maxNeurons );
523 log <<
"*****************************************"
524 "**************************************\n";
529template <
class t_device>
533 log <<
"*** SETUP: NEURAL NETWORK WEIGHTS *******"
534 "**************************************\n";
537 log <<
strpr(
"Weight file name format: %s\n",
538 fileNameFormat.c_str() );
541 for ( vector<ElementCabana>::iterator it = elements.begin(); it != elements.end();
544 const char *estring = elementStrings[count].c_str();
545 for (
size_t i = 0; i < knownElements.size(); ++i )
547 if ( strcmp( knownElements[i].c_str(), estring ) == 0 )
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() );
558 file.open( fileName.c_str() );
559 if ( !file.is_open() )
561 throw runtime_error(
"ERROR: Could not open file: \"" + fileName +
565 int attype = it->getIndex();
566 int layer, start, end;
567 while ( getline( file, line ) )
569 if ( line.at( 0 ) !=
'#' )
571 vector<string> splitLine =
split(
reduce( line ) );
572 if ( strcmp( splitLine.at( 1 ).c_str(),
"a" ) == 0 )
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() );
580 else if ( strcmp( splitLine.at( 1 ).c_str(),
"b" ) == 0 )
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() );
592 log <<
"*****************************************"
593 "**************************************\n";
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(
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 )
611 Cabana::deep_copy( G, 0.0 );
613 Kokkos::RangePolicy<exe_space> policy( 0, N_local );
616 auto numSFGperElem_ = numSFGperElem;
617 auto SFGmemberlist_ = d_SFGmemberlist;
619 auto SFscaling_ = d_SFscaling;
620 auto maxSFperElem_ = maxSFperElem;
621 auto convLength_ = convLength;
622 auto cutoffType_ = cutoffType;
623 auto cutoffAlpha_ = cutoffAlpha;
625 auto calc_radial_symm_op = KOKKOS_LAMBDA(
const int i,
const int j )
631 int memberindex, globalIndex;
633 T_F_FLOAT dxij, dyij, dzij;
635 int attype = type( i );
636 for (
int groupIndex = 0; groupIndex < numSFGperElem_( attype );
639 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
642 size_t memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
643 size_t e1 = SF_( attype, memberindex0, 2 );
644 double rc = SF_( attype, memberindex0, 7 );
646 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
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;
654 if ( e1 == nej && rij < rc )
656 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
658 for (
size_t k = 0; k < size; ++k )
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;
671 Cabana::neighbor_parallel_for(
672 policy, calc_radial_symm_op, neigh_list, Cabana::FirstNeighborsTag(),
673 neigh_op_tag,
"Mode::calculateRadialSymmetryFunctionGroups" );
676 auto calc_angular_symm_op =
677 KOKKOS_LAMBDA(
const int i,
const int j,
const int k )
679 double pfcij = 0.0, pdfcij = 0.0;
680 double pfcik = 0.0, pdfcik = 0.0;
681 double pfcjk = 0.0, pdfcjk = 0.0;
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;
688 int attype = type( i );
689 for (
int groupIndex = 0; groupIndex < numSFGperElem_( attype );
692 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
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 );
700 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
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;
708 if ( ( e1 == nej || e2 == nej ) && rij < rc )
711 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
716 if ( ( e1 == nej && e2 == nek ) ||
717 ( e2 == nej && e1 == nek ) )
720 ( x( i, 0 ) - x( k, 0 ) ) *
CFLENGTH * convLength_;
722 ( x( i, 1 ) - x( k, 1 ) ) *
CFLENGTH * convLength_;
724 ( x( i, 2 ) - x( k, 2 ) ) *
CFLENGTH * convLength_;
725 r2ik = dxik * dxik + dyik * dyik + dzik * dzik;
732 r2jk = dxjk * dxjk + dyjk * dyjk + dzjk * dzjk;
733 if ( r2jk < rc * rc )
736 compute_cutoff( cutoffType_, cutoffAlpha_,
737 pfcik, pdfcik, rik, rc,
false );
740 compute_cutoff( cutoffType_, cutoffAlpha_,
741 pfcjk, pdfcjk, rjk, rc,
false );
743 double const rinvijik = 1.0 / rij / rik;
744 double const costijk =
745 ( dxij * dxik + dyij * dyik +
748 double vexp = 0.0, rijs = 0.0, riks = 0.0,
750 for (
size_t l = 0; l < size; ++l )
754 SFGmemberlist_( attype,
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 );
768 vexp = exp( -eta * ( rijs * rijs +
774 ( r2ij + r2ik + r2jk ) );
775 double const plambda =
776 1.0 + lambda * costijk;
778 if ( plambda <= 0.0 )
781 fg *= pow( plambda, ( zeta - 1.0 ) );
782 G( i, globalIndex ) +=
783 fg * plambda * pfcij * pfcik * pfcjk;
792 Cabana::neighbor_parallel_for(
793 policy, calc_angular_symm_op, neigh_list, Cabana::SecondNeighborsTag(),
794 angle_op_tag,
"Mode::calculateAngularSymmetryFunctionGroups" );
797 auto scale_symm_op = KOKKOS_LAMBDA(
const int i )
799 int attype = type( i );
802 int memberindex, globalIndex;
803 double raw_value = 0.0;
804 for (
int groupIndex = 0; groupIndex < numSFGperElem_( attype );
807 memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
809 size_t size = SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
810 for (
size_t k = 0; k < size; ++k )
813 attype, SFGmemberlist_( attype, groupIndex, k ), 14 );
814 memberindex = SFGmemberlist_( attype, groupIndex, k );
816 if ( SF_( attype, memberindex0, 1 ) == 2 )
817 raw_value = G( i, globalIndex );
818 else if ( SF_( attype, memberindex0, 1 ) == 3 )
820 G( i, globalIndex ) *
821 pow( 2, ( 1 - SF_( attype, memberindex, 6 ) ) );
823 G( i, globalIndex ) =
824 scale( attype, raw_value, memberindex, SFscaling_ );
828 Kokkos::parallel_for(
"Mode::scaleSymmetryFunctionGroups", policy,
833template <
class t_device>
834template <
class t_slice_type,
class t_slice_G,
class t_slice_dEdG,
837 t_slice_type type, t_slice_G G, t_slice_dEdG dEdG, t_slice_E E,
int N_local )
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 );
844 Kokkos::RangePolicy<exe_space> policy( 0, N_local );
847 auto numSFperElem_ = numSFperElem;
848 auto numNeuronsPerLayer_ = numNeuronsPerLayer;
849 auto numLayers_ = numLayers;
850 auto numHiddenLayers_ = numHiddenLayers;
852 auto weights_ = weights;
855 auto calc_nn_op = KOKKOS_LAMBDA(
const int atomindex )
857 int attype = type( atomindex );
859 int layer_0, layer_lminusone;
860 layer_0 = (int)numSFperElem_( attype );
862 for (
int k = 0; k < layer_0; ++k )
863 NN( atomindex, 0, k ) = G( atomindex, k );
865 for (
int l = 1; l < numLayers_; l++ )
868 layer_lminusone = layer_0;
870 layer_lminusone = numNeuronsPerLayer_( l - 1 );
872 for (
int i = 0; i < numNeuronsPerLayer_( l ); i++ )
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 );
881 NN( atomindex, l, i ) = dtmp;
882 dfdx( atomindex, l, i ) = 1.0;
884 else if ( AF_( l ) == 1 )
887 NN( atomindex, l, i ) = dtmp;
888 dfdx( atomindex, l, i ) = 1.0 - dtmp * dtmp;
893 E( atomindex ) = NN( atomindex, numLayers_ - 1, 0 );
896 for (
int k = 0; k < numNeuronsPerLayer_( 0 ); k++ )
898 for (
int i = 0; i < numNeuronsPerLayer_( 1 ); i++ )
899 inner( atomindex, 0, i ) =
900 weights_( attype, 0, i, k ) * dfdx( atomindex, 1, i );
902 for (
int l = 1; l < numHiddenLayers_ + 1; l++ )
904 for (
int i2 = 0; i2 < numNeuronsPerLayer_( l + 1 ); i2++ )
906 outer( atomindex, l - 1, i2 ) = 0.0;
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 );
915 if ( l < numHiddenLayers_ )
916 inner( atomindex, l, i2 ) =
917 outer( atomindex, l - 1, i2 );
920 dEdG( atomindex, k ) = outer( atomindex, numHiddenLayers_ - 1, 0 );
923 Kokkos::parallel_for(
"Mode::calculateAtomicNeuralNetworks", policy,
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 )
937 double convForce_ = convLength / convEnergy;
939 Kokkos::RangePolicy<exe_space> policy( 0, N_local );
942 auto numSFGperElem_ = numSFGperElem;
943 auto SFGmemberlist_ = d_SFGmemberlist;
945 auto SFscaling_ = d_SFscaling;
946 auto maxSFperElem_ = maxSFperElem;
947 auto convLength_ = convLength;
948 auto cutoffType_ = cutoffType;
949 auto cutoffAlpha_ = cutoffAlpha;
951 auto calc_radial_force_op = KOKKOS_LAMBDA(
const int i,
const int j )
956 T_F_FLOAT dxij, dyij, dzij;
958 int memberindex, globalIndex;
960 int attype = type( i );
962 for (
int groupIndex = 0; groupIndex < numSFGperElem_( attype );
965 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
968 size_t memberindex0 = SFGmemberlist_( attype, groupIndex, 0 );
969 size_t e1 = SF_( attype, memberindex0, 2 );
970 double rc = SF_( attype, memberindex0, 7 );
972 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
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;
980 if ( e1 == nej && rij < rc )
984 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
986 for (
size_t k = 0; k < size; ++k )
989 attype, SFGmemberlist_( attype, groupIndex, k ),
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 ) );
997 SFscaling_( attype, memberindex, 6 ) *
998 ( pdfcij - 2.0 * eta * ( rij - rs ) * pfcij ) *
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_ );
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_ );
1018 Cabana::neighbor_parallel_for( policy, calc_radial_force_op, neigh_list,
1019 Cabana::FirstNeighborsTag(), neigh_op_tag,
1020 "Mode::calculateRadialForces" );
1023 auto calc_angular_force_op =
1024 KOKKOS_LAMBDA(
const int i,
const int j,
const int k )
1027 double pdfcij = 0.0;
1028 double pfcik, pdfcik, pfcjk, pdfcjk;
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;
1035 int attype = type( i );
1036 for (
int groupIndex = 0; groupIndex < numSFGperElem_( attype );
1039 if ( SF_( attype, SFGmemberlist_( attype, groupIndex, 0 ), 1 ) ==
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 );
1047 SFGmemberlist_( attype, groupIndex, maxSFperElem_ );
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;
1055 if ( ( e1 == nej || e2 == nej ) && rij < rc )
1058 compute_cutoff( cutoffType_, cutoffAlpha_, pfcij, pdfcij,
1062 if ( ( e1 == nej && e2 == nek ) ||
1063 ( e2 == nej && e1 == nek ) )
1066 ( x( i, 0 ) - x( k, 0 ) ) *
CFLENGTH * convLength_;
1068 ( x( i, 1 ) - x( k, 1 ) ) *
CFLENGTH * convLength_;
1070 ( x( i, 2 ) - x( k, 2 ) ) *
CFLENGTH * convLength_;
1071 r2ik = dxik * dxik + dyik * dyik + dzik * dzik;
1078 r2jk = dxjk * dxjk + dyjk * dyjk + dzjk * dzjk;
1079 if ( r2jk < rc * rc )
1082 compute_cutoff( cutoffType_, cutoffAlpha_,
1083 pfcik, pdfcik, rik, rc,
true );
1086 compute_cutoff( cutoffType_, cutoffAlpha_,
1087 pfcjk, pdfcjk, rjk, rc,
true );
1089 double const rinvijik = 1.0 / rij / rik;
1090 double const costijk =
1091 ( dxij * dxik + dyij * dyik +
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,
1101 for (
size_t l = 0; l < size; ++l )
1105 SFGmemberlist_( attype,
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 );
1119 vexp = exp( -eta * ( rijs * rijs +
1124 vexp = exp( -eta * r2sum );
1126 double const plambda =
1127 1.0 + lambda * costijk;
1129 if ( plambda <= 0.0 )
1132 fg *= pow( plambda, ( zeta - 1.0 ) );
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;
1146 ( rinvijik - costijk / r2ij -
1147 p2etapl * rijs / rij ) +
1151 ( rinvijik - costijk / r2ik -
1152 p2etapl * riks / rik ) +
1156 ( pfczl * ( rinvijik +
1157 p2etapl * rjks / rjk ) -
1162 p1 = fg * ( pfczl * ( rinvijik -
1166 p2 = fg * ( pfczl * ( rinvijik -
1171 ( pfczl * ( rinvijik + p2etapl ) -
1174 f_a( i, 0 ) -= ( dEdG( i, globalIndex ) *
1175 ( p1 * dxij + p2 * dxik ) *
1177 f_a( i, 1 ) -= ( dEdG( i, globalIndex ) *
1178 ( p1 * dyij + p2 * dyik ) *
1180 f_a( i, 2 ) -= ( dEdG( i, globalIndex ) *
1181 ( p1 * dzij + p2 * dzik ) *
1184 f_a( j, 0 ) += ( dEdG( i, globalIndex ) *
1185 ( p1 * dxij + p3 * dxjk ) *
1187 f_a( j, 1 ) += ( dEdG( i, globalIndex ) *
1188 ( p1 * dyij + p3 * dyjk ) *
1190 f_a( j, 2 ) += ( dEdG( i, globalIndex ) *
1191 ( p1 * dzij + p3 * dzjk ) *
1194 f_a( k, 0 ) += ( dEdG( i, globalIndex ) *
1195 ( p2 * dxik - p3 * dxjk ) *
1197 f_a( k, 1 ) += ( dEdG( i, globalIndex ) *
1198 ( p2 * dyik - p3 * dyjk ) *
1200 f_a( k, 2 ) += ( dEdG( i, globalIndex ) *
1201 ( p2 * dzik - p3 * dzjk ) *
1211 Cabana::neighbor_parallel_for( policy, calc_angular_force_op, neigh_list,
1212 Cabana::SecondNeighborsTag(), angle_op_tag,
1213 "Mode::calculateAngularForces" );
Derived Cabana class for element-specific data.
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
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
typename device_type::memory_space memory_space
Kokkos::View< T_INT *, layout, host_space > h_t_int
Kokkos::View< T_INT ***, layout, host_space > t_SFGmemberlist
Kokkos::View< T_FLOAT ****, layout, host_space > t_weights
Kokkos::View< T_FLOAT ***, memory_space > d_t_NN
Kokkos::View< T_V_FLOAT *, layout, host_space > h_t_mass
Kokkos::View< T_FLOAT **[8], layout, host_space > t_SFscaling
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.
string strpr(const char *format,...)
String version of printf function.
vector< string > split(string const &input, char delimiter)
Split string at each delimiter.
string reduce(string const &line, string const &whitespace, string const &fill)
Replace multiple whitespaces with fill.
constexpr double CFLENGTH