From fcf8500887110c270141766850c902fba76d0e9d Mon Sep 17 00:00:00 2001 From: Ajinkya Hire Date: Mon, 15 Apr 2024 10:37:21 -0400 Subject: [PATCH 1/6] Added uf3_read_unified_pot_file() to read single potential file on rank 0 and communicate() to broadcast the data to other ranks Added one_ceoff --- src/ML-UF3/pair_uf3.cpp | 926 +++++++++++++++++++++++++++++++++++++++- src/ML-UF3/pair_uf3.h | 22 + 2 files changed, 935 insertions(+), 13 deletions(-) diff --git a/src/ML-UF3/pair_uf3.cpp b/src/ML-UF3/pair_uf3.cpp index b6bdd7705bd..b6986d422fd 100644 --- a/src/ML-UF3/pair_uf3.cpp +++ b/src/ML-UF3/pair_uf3.cpp @@ -44,6 +44,7 @@ namespace LAMMPS_NS{ std::unordered_map>>> n3b_coeff_matrix; std::vector> UFBS2b; std::vector>> UFBS3b; + }; } @@ -58,12 +59,24 @@ PairUF3::PairUF3(LAMMPS *lmp) : { uf3_impl = new UF3Impl; single_enable = 1; // 1 if single() routine exists + one_coeff = 1; // 1 if allows only one coeff * * call restartinfo = 0; // 1 if pair style writes restart info maxshort = 10; neighshort = nullptr; centroidstressflag = CENTROID_AVAIL; manybody_flag = 1; bsplines_created = 0; + + n2b_knots_array = nullptr; + n2b_coeff_array = nullptr; + n2b_knots_array_size = nullptr; + n2b_coeff_array_size = nullptr; + + map_3b = nullptr; + n3b_knots_array = nullptr; + n3b_coeff_array = nullptr; + n3b_knots_array_size = nullptr; + n3b_coeff_array_size = nullptr; } /* ---------------------------------------------------------------------- */ @@ -76,6 +89,10 @@ PairUF3::~PairUF3() memory->destroy(cutsq); memory->destroy(cut); memory->destroy(knot_spacing_type_2b); + memory->destroy(n2b_knots_array_size); + memory->destroy(n2b_coeff_array_size); + memory->destroy(n2b_knots_array); + memory->destroy(n2b_coeff_array); if (pot_3b) { memory->destroy(setflag_3b); @@ -84,6 +101,11 @@ PairUF3::~PairUF3() memory->destroy(min_cut_3b); memory->destroy(neighshort); memory->destroy(knot_spacing_type_3b); + memory->destroy(map_3b); + memory->destroy(n3b_knots_array_size); + memory->destroy(n3b_coeff_array_size); + memory->destroy(n3b_knots_array); + memory->destroy(n3b_coeff_array); } } delete uf3_impl; @@ -115,6 +137,7 @@ void PairUF3::settings(int narg, char **arg) tot_pot_files = n2body_pot_files + n3body_pot_files; } else error->all(FLERR, "Pair style uf3 not (yet) implemented for {}-body terms", nbody_flag); + } /* ---------------------------------------------------------------------- @@ -122,11 +145,19 @@ void PairUF3::settings(int narg, char **arg) * ---------------------------------------------------------------------- */ void PairUF3::coeff(int narg, char **arg) { + if (narg != 3+atom->ntypes) + error->all(FLERR, "Invalid number of arguments uf3 in pair coeffs."); + if (!allocated) allocate(); - if (narg != 3 && narg != 5) error->all(FLERR, "Invalid number of arguments uf3 in pair coeffs."); + map_element2type(narg-3, arg+3, false); + + if (comm->me == 0) + uf3_read_unified_pot_file(arg[2]); + communicate(); + //if (narg != 3 && narg != 5) error->all(FLERR, "Invalid number of arguments uf3 in pair coeffs."); - int ilo, ihi, jlo, jhi, klo, khi; + /*int ilo, ihi, jlo, jhi, klo, khi; if (narg == 3) { utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error); utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error); @@ -145,6 +176,87 @@ void PairUF3::coeff(int narg, char **arg) for (int k = MAX(klo, jlo); k <= khi; k++) uf3_read_pot_file(i, j, k, arg[4]); } } + }*/ +} + +//Broadcast data read from potential file to all processors +void PairUF3::communicate() +{ + const int num_of_elements = atom->ntypes; + MPI_Bcast(&cut[0][0], (num_of_elements + 1)*(num_of_elements + 1), + MPI_DOUBLE, 0, world); + + MPI_Bcast(&n2b_knots_array_size[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + MPI_Bcast(&n2b_coeff_array_size[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + MPI_Bcast(&max_num_knots_2b, 1, MPI_INT, 0, world); + MPI_Bcast(&max_num_coeff_2b, 1, MPI_INT, 0, world); + + if (pot_3b){ + MPI_Bcast(&cut_3b_list[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_DOUBLE, 0, world); + + MPI_Bcast(&cut_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_DOUBLE, 0, world); + + MPI_Bcast(&n3b_knots_array_size[0][0], tot_interaction_count_3b*3, + MPI_INT, 0, world); + MPI_Bcast(&n3b_coeff_array_size[0][0], tot_interaction_count_3b*3, + MPI_INT, 0, world); + + MPI_Bcast(&max_num_knots_3b, 1, MPI_INT, 0, world); + MPI_Bcast(&max_num_coeff_3b, 1, MPI_INT, 0, world); + } + + if (comm->me != 0) { + memory->destroy(n2b_knots_array); + memory->destroy(n2b_coeff_array); + + memory->create(n2b_knots_array, num_of_elements + 1, num_of_elements + 1, + max_num_knots_2b, "pair:n2b_knots_array"); + memory->create(n2b_coeff_array, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, "pair:n2b_coeff_array"); + if (pot_3b) { + memory->destroy(n3b_knots_array); + memory->destroy(n3b_coeff_array); + + memory->create(n3b_knots_array, tot_interaction_count_3b, 3, + max_num_knots_3b, "pair:n3b_knots_array"); + + memory->create(n3b_coeff_array, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:n3b_coeff_array"); + } + } + + MPI_Bcast(&knot_spacing_type_2b[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + MPI_Bcast(&n2b_knots_array[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*max_num_knots_2b, MPI_DOUBLE, 0, world); + MPI_Bcast(&n2b_coeff_array[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*max_num_coeff_2b, MPI_DOUBLE, 0, world); + + MPI_Bcast(&setflag[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + if (pot_3b) { + MPI_Bcast(&knot_spacing_type_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_INT, 0, world); + MPI_Bcast(&n3b_knots_array[0][0][0], + tot_interaction_count_3b*3*max_num_knots_3b, MPI_DOUBLE, 0, world); + MPI_Bcast(&n3b_coeff_array[0][0][0][0], + tot_interaction_count_3b*max_num_coeff_3b*max_num_coeff_3b*max_num_coeff_3b, + MPI_DOUBLE, 0, world); + MPI_Bcast(&setflag_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_INT, 0, world); + MPI_Bcast(&min_cut_3b[0][0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1)*3, + MPI_DOUBLE, 0, world); } } @@ -153,6 +265,8 @@ void PairUF3::allocate() allocated = 1; const int num_of_elements = atom->ntypes; + map = new int[num_of_elements+1]; //No need to delete map as ~Pair deletes map + // Contains info about wether UF potential were found for type i and j memory->create(setflag, num_of_elements + 1, num_of_elements + 1, "pair:setflag"); @@ -168,6 +282,12 @@ void PairUF3::allocate() memory->create(knot_spacing_type_2b, num_of_elements + 1, num_of_elements + 1, "pair:knot_spacing_2b"); + //Contains size of 2b knots vectors and 2b coeff matrices + memory->create(n2b_knots_array_size, num_of_elements + 1, num_of_elements + 1, + "pair:n2b_knots_array_size"); + memory->create(n2b_coeff_array_size, num_of_elements + 1, num_of_elements + 1, + "pair:n2b_coeff_array_size"); + // Contains knot_vect of 2-body potential for type i and j uf3_impl->n2b_knot.resize(num_of_elements + 1); uf3_impl->n2b_coeff.resize(num_of_elements + 1); @@ -196,7 +316,12 @@ void PairUF3::allocate() memory->create(knot_spacing_type_3b, num_of_elements + 1, num_of_elements + 1, num_of_elements + 1, "pair:knot_spacing_3b"); - // setting cut_3b and setflag = 0 + tot_interaction_count_3b = 0; + //conatins map of I-J-K interaction + memory->create(map_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:map_3b"); + + // setting cut_3b, setflag = 0 and map_3b for (int i = 1; i < num_of_elements + 1; i++) { for (int j = 1; j < num_of_elements + 1; j++) { cut_3b_list[i][j] = 0; @@ -205,9 +330,21 @@ void PairUF3::allocate() min_cut_3b[i][j][k][0] = 0; min_cut_3b[i][j][k][1] = 0; min_cut_3b[i][j][k][2] = 0; + + setflag_3b[i][j][k] = 0; + + map_3b[i][j][k] = tot_interaction_count_3b; + tot_interaction_count_3b++; } } } + + //contains sizes of 3b knots vectors and 3b coeff matrices + memory->create(n3b_knots_array_size, tot_interaction_count_3b, 3, + "pair:n3b_knots_array_size"); + memory->create(n3b_coeff_array_size, tot_interaction_count_3b, 3, + "pair:n3b_coeff_array_size"); + uf3_impl->n3b_knot_matrix.resize(num_of_elements + 1); uf3_impl->UFBS3b.resize(num_of_elements + 1); for (int i = 1; i < num_of_elements + 1; i++) { @@ -219,6 +356,732 @@ void PairUF3::allocate() } } memory->create(neighshort, maxshort, "pair:neighshort"); + + } +} + +void PairUF3::uf3_read_unified_pot_file(char *potf_name) +{ + //Go through the entire file and get the sizes of knot vectors and + //coeff vectors/matrices + // + //Create arrays + // + //Go through the file again and read the knots and coefficients + // + + const int num_of_elements = atom->ntypes; + + //if (true) { + FILE *fp = utils::open_potential(potf_name, lmp, nullptr); + if (!fp) + error->all(FLERR, + "Cannot open UF3 potential file {}: {}", + potf_name, utils::getsyserror()); + + TextFileReader txtfilereader(fp, "UF3:POTFP"); + txtfilereader.ignore_comments = false; + + //while loop over the entire file, find blocks starting with #UF3 POT + //if block found read the very next line to determine 2B or 3B block + //if 2B read the knot vector and coeff vector size + //if 3B read the knot vectors and coeff matrix size + int line_counter = 1; + char *line; + while((line = txtfilereader.next_line(1))){ + Tokenizer line_token(line); + + //Detect start of a block + if (line_token.contains("#UF3 POT")) { + //Block start detected + if (line_token.contains("UNITS:") == 0) + error->all(FLERR, + "UF3: {} file does not contain the 'UNITS:' metadata in " + "the header", + potf_name); + + //Read the 2nd line of the block + std::string temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp2nd_line(temp_line); + + std::string nbody_on_file = fp2nd_line.next_string(); + if (nbody_on_file == "2B") { + //2B block + if (fp2nd_line.count() != 6) + error->all(FLERR, "UF3: Expected 6 words on line {} of {} file " + "but found {} word/s", + line_counter, potf_name, fp2nd_line.count()); + + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + for (int i=1; iall(FLERR, + "UF3: Current implementation is throughly tested only " + "for leading_trim=0"); + if (trailing_trim != 3) + error->all(FLERR, + "UF3: Current implementation is throughly tested only " + "for trailing_trim=3"); + + //read next line, should contain cutoff and size of knot vector + temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp3rd_line(temp_line); + if (fp3rd_line.count() != 2) + error->all(FLERR, + "UF3: Expected only 2 words on 3rd line => " + "Rij_CUTOFF NUM_OF_KNOTS. Found {} word/s", + fp3rd_line.count()); + + //cut is used in init_one which is called by pair.cpp at line 267 + //where the return of init_one is squared + cut[itype][jtype] = fp3rd_line.next_double(); //MPI_Bcast + cut[jtype][itype] = cut[itype][jtype]; + + int num_knots_2b = fp3rd_line.next_int(); + n2b_knots_array_size[itype][jtype] = num_knots_2b; //MPI_Bcast + n2b_knots_array_size[jtype][itype] = num_knots_2b; //MPI_Bcast + max_num_knots_2b = std::max(max_num_knots_2b, num_knots_2b); //MPI_Bcast + + //skip next line + txtfilereader.skip_line(); + line_counter++; + + //read number of coeff + temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp5th_line(temp_line); + + int num_coeff_2b = fp5th_line.next_int(); + n2b_coeff_array_size[itype][jtype] = num_coeff_2b; //MPI_Bcast + n2b_coeff_array_size[jtype][itype] = num_coeff_2b; //MPI_Bcast + max_num_coeff_2b = std::max(max_num_coeff_2b, num_coeff_2b); //MPI_Bcast + } + } + else if ((nbody_on_file == "3B") && (pot_3b)) { + //3B block + if (fp2nd_line.count() != 7) + error->all(FLERR, "UF3: Expected 7 words on line {} of {} file" + "but found {} word/s", + line_counter, potf_name, fp2nd_line.count()); + + if (nbody_on_file == "3B") { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + std::string element3 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + int ktype = 0; + for (int i=1; iall(FLERR, + "UF3: Current implementation is throughly tested " + "only for leading_trim=0"); + if (trailing_trim != 3) + error->all(FLERR, + "UF3: Current implementation is throughly tested " + "only for trailing_trim=3"); + + //read next line, should contain cutoffs and size of knot vectors + temp_line = txtfilereader.next_line(6); + line_counter++; + ValueTokenizer fp3rd_line(temp_line); + + if (fp3rd_line.count() != 6) + error->all(FLERR, + "UF3: Expected only 6 numbers on 3rd line => " + "Rjk_CUTOFF Rik_CUTOFF Rij_CUTOFF NUM_OF_KNOTS_JK " + "NUM_OF_KNOTS_IK NUM_OF_KNOTS_IJ Found {} number/s", + fp3rd_line.count()); + + double cut3b_rjk = fp3rd_line.next_double(); + double cut3b_rij = fp3rd_line.next_double(); + double cut3b_rik = fp3rd_line.next_double(); + + if (cut3b_rij != cut3b_rik) + error->all(FLERR, + "UF3: rij!=rik for {}-{}-{}. " + "Current implementation only works for rij=rik", + element1, element2, element3); + + if (2 * cut3b_rik != cut3b_rjk) + error->all(FLERR, + "UF3: 2rij=2rik!=rik for {}-{}-{}. " + "Current implementation only works for 2rij=2rik!=rik", + element1, element2, element3); + + cut_3b_list[itype][jtype] = + std::max(cut3b_rij, cut_3b_list[itype][jtype]); //MPI_Bcast + cut_3b_list[itype][ktype] = + std::max(cut_3b_list[itype][ktype], cut3b_rik); //MPI_Bcast + + cut_3b[itype][jtype][ktype] = cut3b_rij; //MPI_Bcast + cut_3b[itype][ktype][jtype] = cut3b_rik; //MPI_Bcast + + int num_knots_3b_jk = fp3rd_line.next_int(); + int num_knots_3b_ik = fp3rd_line.next_int(); + int num_knots_3b_ij = fp3rd_line.next_int(); + + n3b_knots_array_size[map_3b[itype][jtype][ktype]][0] = num_knots_3b_jk; //MPI_Bcast + n3b_knots_array_size[map_3b[itype][jtype][ktype]][1] = num_knots_3b_ik; + n3b_knots_array_size[map_3b[itype][jtype][ktype]][2] = num_knots_3b_ij; + + n3b_knots_array_size[map_3b[itype][ktype][jtype]][0] = num_knots_3b_jk; //MPI_Bcast + n3b_knots_array_size[map_3b[itype][ktype][jtype]][1] = num_knots_3b_ij; + n3b_knots_array_size[map_3b[itype][ktype][jtype]][2] = num_knots_3b_ik; + + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_jk); + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_ik); + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_ij); //MPI_Bcast + + //skip next 3 line + txtfilereader.skip_line(); + line_counter++; + txtfilereader.skip_line(); + line_counter++; + txtfilereader.skip_line(); + line_counter++; + + //read number of coeff + temp_line = txtfilereader.next_line(3); + line_counter++; + ValueTokenizer fp7th_line(temp_line); + + if (fp7th_line.count() != 3) + error->all(FLERR, + "UF3: Expected 3 numbers on 7th line => " + "SHAPE_OF_COEFF_MATRIX[I][J][K] " + "found {} numbers", + fp7th_line.count()); + + int coeff_matrix_dim1 = fp7th_line.next_int(); + int coeff_matrix_dim2 = fp7th_line.next_int(); + int coeff_matrix_dim3 = fp7th_line.next_int(); + + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][0] = coeff_matrix_dim1; //MPI_Bcast + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][1] = coeff_matrix_dim2; + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][2] = coeff_matrix_dim3; + + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][0] = coeff_matrix_dim2; + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][1] = coeff_matrix_dim1; + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][2] = coeff_matrix_dim3; + + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim1); + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim2); + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim3); + } + } + } + else { + if (!((nbody_on_file == "3B") && (!pot_3b))) + error->all(FLERR, + "UF3: Expected either '2B' or '3B' word on line {} of {} file", + line_counter, potf_name); + } + } //if of #UF3 POT + line_counter++; + } // while + //fclose(fp); + + //Create knot and coeff arrays + if (max_num_knots_2b > 0) { + //if (comm->me == 0) + memory->create(n2b_knots_array, num_of_elements + 1, num_of_elements + 1, + max_num_knots_2b, "pair:n2b_knots_array"); + } + else + error->all(FLERR, + "UF3: Error reading the size of 2B knot vector\n" + "Possibly no 2B UF3 potential block detected in {} file", + potf_name); + + if (max_num_coeff_2b > 0) { + //if (comm->me == 0) + /*utils::logmesg(lmp, + "max_num_coeff_2b = {}\n", max_num_coeff_2b);*/ + memory->create(n2b_coeff_array, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, "pair:n2b_coeff_array"); + } + else + error->all(FLERR, + "UF3: Error reading the size of 2B coeff vector\n" + "Possibly no 2B UF3 potential block detected in {} file", + potf_name); + + if (pot_3b) { + if (max_num_knots_3b > 0) + memory->create(n3b_knots_array, tot_interaction_count_3b, 3, + max_num_knots_3b, "pair:n3b_knots_array"); + + else + error->all(FLERR, + "UF3: Error reading the size of 3B knot vector\n" + "Possibly no 3B UF3 potential block detected in {} file", + potf_name); + + if (max_num_coeff_3b > 0) + memory->create(n3b_coeff_array, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:n3b_coeff_array"); + else + error->all(FLERR, + "UF3: Error reading the size of 3B coeff matrices\n" + "Possibly no 3B UF3 potential block detected in {} file", + potf_name); + } + + //Go back to the begning of the file + txtfilereader.rewind(); + + //Go through the file again and fill knot and coeff arrays + //while loop to read the data + //if (true) { + /*FILE *fp = utils::open_potential(potf_name, lmp, nullptr); + if (!fp) + error->all(FLERR, + "Cannot open UF3 potential file {}: {}", + potf_name, utils::getsyserror()); + + TextFileReader txtfilereader(fp, "UF3:POTFP"); + txtfilereader.ignore_comments = false; + char *line;*/ + while((line = txtfilereader.next_line(1))){ + Tokenizer line_token(line); + + //Detect start of a block + if (line_token.contains("#UF3 POT")) { + //Block start detected + //Read the 2nd line of the block + std::string temp_line = txtfilereader.next_line(1); + ValueTokenizer fp2nd_line(temp_line); + std::string nbody_on_file = fp2nd_line.next_string(); + + if (nbody_on_file == "2B") { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + for (int i=1; iall(FLERR, + "UF3: Expected either 'uk'(uniform-knots) or 'nk'(non-uniform knots). " + "Found {} on the 2nd line of {}-{} interaction block", + knot_type, element1, element2); + + if ((itype != 0) && (jtype != 0)) { + //skip line containing info of cutoff and knot vect size + txtfilereader.skip_line(); + + int num_knots_2b = n2b_knots_array_size[itype][jtype]; + + temp_line = txtfilereader.next_line(num_knots_2b); + ValueTokenizer fp4th_line(temp_line); + + if (fp4th_line.count() != num_knots_2b) + error->all(FLERR, "UF3: Error readig the 2B potential block for {}-{}\n" + "Expecter {} numbers on 4th line of the block but found {} " + "numbers", num_knots_2b,fp4th_line.count()); + + for (int k = 0; k < num_knots_2b; k++) { + n2b_knots_array[itype][jtype][k] = fp4th_line.next_double(); //MPI_Bcast + n2b_knots_array[jtype][itype][k] = n2b_knots_array[itype][jtype][k]; + } + + //skip next line + txtfilereader.skip_line(); + + int num_of_coeff_2b = n2b_coeff_array_size[itype][jtype]; + + temp_line = txtfilereader.next_line(num_of_coeff_2b); + ValueTokenizer fp6th_line(temp_line); + + if (fp6th_line.count() != num_of_coeff_2b) + error->all(FLERR, + "UF3: Error readig the 2B potential block for {}-{}\n" + "Expecter {} numbers on 6th line of the block but found {} " + "numbers", num_knots_2b,fp4th_line.count()); + + for (int k = 0; k < num_of_coeff_2b; k++) { + n2b_coeff_array[itype][jtype][k] = fp6th_line.next_double(); //MPI_Bcast + n2b_coeff_array[jtype][itype][k] = n2b_coeff_array[itype][jtype][k]; + } + + if (num_knots_2b != num_of_coeff_2b + 4) + error->all(FLERR, + "UF3: {}-{} interaction block has incorrect knot and " + "coeff data nknots!=ncoeffs + 3 + 1", + element1, element2); + + setflag[itype][jtype] = 1; //MPI_Bcast + setflag[jtype][itype] = 1; + } + } + + if ((nbody_on_file == "3B") && (pot_3b)) { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + std::string element3 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + int ktype = 0; + for (int i=1; iall(FLERR, + "UF3: Expected either 'uk'(uniform-knots) or 'nk'(non-uniform knots) " + "Found {} on the 2nd line of {}-{}-{} interaction block", + knot_type, element1, element2, element3); + + if ((itype != 0) && (jtype != 0) && (ktype!=0)) { + //skip line containing info of cutoffs and knot vector sizes + txtfilereader.skip_line(); + + int num_knots_3b_jk = n3b_knots_array_size[map_3b[itype][jtype][ktype]][0]; + int num_knots_3b_ik = n3b_knots_array_size[map_3b[itype][jtype][ktype]][1]; + int num_knots_3b_ij = n3b_knots_array_size[map_3b[itype][jtype][ktype]][2]; + + temp_line = txtfilereader.next_line(num_knots_3b_jk); + ValueTokenizer fp4th_line(temp_line); + if (fp4th_line.count() != num_knots_3b_jk) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 4th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_jk, fp4th_line.count()); + + for (int i = 0; i < num_knots_3b_jk; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][0][i] = + fp4th_line.next_double(); //MPI_Bcast + n3b_knots_array[map_3b[itype][ktype][jtype]][0][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][i]; + } + + min_cut_3b[itype][jtype][ktype][0] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][0]; //MPI_Bcast + min_cut_3b[itype][ktype][jtype][0] = + n3b_knots_array[map_3b[itype][ktype][jtype]][0][0]; + + temp_line = txtfilereader.next_line(num_knots_3b_ik); + ValueTokenizer fp5th_line(temp_line); + if (fp5th_line.count() != num_knots_3b_ik) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 5th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_ik, fp5th_line.count()); + + for (int i = 0; i < num_knots_3b_ik; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][1][i] = + fp5th_line.next_double(); //MPI_Bcast + n3b_knots_array[map_3b[itype][ktype][jtype]][2][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][i]; + } + + min_cut_3b[itype][jtype][ktype][1] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][0]; + min_cut_3b[itype][ktype][jtype][2] = + n3b_knots_array[map_3b[itype][ktype][jtype]][2][0]; + + temp_line = txtfilereader.next_line(num_knots_3b_ij); + ValueTokenizer fp6th_line(temp_line); + if (fp6th_line.count() != num_knots_3b_ij) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 6th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_ij, fp6th_line.count()); + + for (int i = 0; i < num_knots_3b_ij; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][2][i] = + fp6th_line.next_double(); + n3b_knots_array[map_3b[itype][ktype][jtype]][1][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][2][i]; + } + + min_cut_3b[itype][jtype][ktype][2] = n3b_knots_array[map_3b[itype][jtype][ktype]][2][0]; + min_cut_3b[itype][ktype][jtype][1] = n3b_knots_array[map_3b[itype][ktype][jtype]][1][0]; + + //skip next line + txtfilereader.skip_line(); + + int coeff_matrix_dim1 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][0]; + int coeff_matrix_dim2 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][1]; + int coeff_matrix_dim3 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][2]; + + if (num_knots_3b_jk != coeff_matrix_dim3 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_JK) and coeff (coeff_matrix_dim3) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + if (num_knots_3b_ik != coeff_matrix_dim2 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_IK) and coeff (coeff_matrix_dim2) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + if (num_knots_3b_ij != coeff_matrix_dim1 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_IJ) and coeff (coeff_matrix_dim1) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + int coeff_matrix_elements_len = coeff_matrix_dim3; + int key1 = map_3b[itype][jtype][ktype]; + int key2 = map_3b[itype][ktype][jtype]; + + int line_count = 0; + for (int i = 0; i < coeff_matrix_dim1; i++) { + for (int j = 0; j < coeff_matrix_dim2; j++) { + temp_line = txtfilereader.next_line(coeff_matrix_elements_len); + ValueTokenizer coeff_line(temp_line); + if (coeff_line.count() != coeff_matrix_elements_len) + error->all(FLERR, + "UF3: Error reading 3B potential block for {}-{}-{}\n" + "Expected {} numbers on {}th line of the block but found {} " + "numbers", element1, element2, element3, + coeff_matrix_elements_len, line_count + 8, + coeff_line.count()); + + for (int k = 0; k < coeff_matrix_dim3; k++) { + n3b_coeff_array[key1][i][j][k] = coeff_line.next_double(); + } + line_count += 1; + } + } + + for (int i = 0; i < coeff_matrix_dim1; i++) { + for (int j = 0; j < coeff_matrix_dim2; j++) { + for (int k = 0; k < coeff_matrix_dim3; k++) { + n3b_coeff_array[key2][j][i][k] = n3b_coeff_array[key1][i][j][k]; //MPI_Bcast + } + } + } + + setflag_3b[itype][jtype][ktype] = 1; //MPI_Bcast + setflag_3b[itype][ktype][jtype] = 1; + } + } + } // if #UF3 POT + } //while + fclose(fp); + + //Set interaction of atom types of the same elements + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + if (setflag[i][j] != 1){ + //i-j interaction not set + + //maybe i-j is mapped to some other atom type interaction? + int i_mapped_to = map[i]+1; //+1 as map starts from 0 + int j_mapped_to = map[j]+1; //+1 as map starts from 0 + + if ((i_mapped_to == i) && (j_mapped_to == j)) + //i-j is not mapped to some other atom type ie interaction is missing on file + error->all(FLERR, + "UF3: Potential for interaction {}-{} ie {}-{} not found " + "in {} file", + i, j, elements[i_mapped_to-1], elements[j_mapped_to-1], + potf_name); + + //utils::logmesg(lmp,"Setting stuff for {}-{} mapped to {}-{}\n",i,j, + // i_mapped_to, j_mapped_to); + + cut[i][j] = cut[i_mapped_to][j_mapped_to]; + + n2b_knots_array_size[i][j] = n2b_knots_array_size[i_mapped_to][j_mapped_to]; + n2b_coeff_array_size[i][j] = n2b_coeff_array_size[i_mapped_to][j_mapped_to]; + + knot_spacing_type_2b[i][j] = knot_spacing_type_2b[i_mapped_to][j_mapped_to]; + + for (int knot_no = 0; knot_no < max_num_knots_2b; knot_no++) + n2b_knots_array[i][j][knot_no] = + n2b_knots_array[i_mapped_to][j_mapped_to][knot_no]; + + for (int coeff_no = 0; coeff_no < max_num_coeff_2b; coeff_no++) + n2b_coeff_array[i][j][coeff_no] = + n2b_coeff_array[i_mapped_to][j_mapped_to][coeff_no]; + + setflag[i][j] = 1; + } + } + } + + if (pot_3b) { + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + //for (int k = j; k < num_of_elements + 1; k++) { + for (int k = 1; k < num_of_elements + 1; k++) { + if (setflag_3b[i][j][k] != 1) { + //i-j-k interaction not set + + //maybe i-j-k is mapped to some other atom type interaction? + int i_mapped_to = map[i]+1; //+1 as map starts from 0 + int j_mapped_to = map[j]+1; //+1 as map starts from 0 + int k_mapped_to = map[k]+1; //+1 as map starts from 0 + + if ((i_mapped_to == i) && (j_mapped_to == j) && (k_mapped_to == k)) + error->all(FLERR, + "UF3: Potential for interaction {}-{}-{} ie {}-{}-{} " + " not found in {} file", + i, j, k, elements[i_mapped_to-1], elements[j_mapped_to-1], + elements[k_mapped_to-1], potf_name); + if (setflag_3b[i_mapped_to][j_mapped_to][k_mapped_to] != 1) + error->all(FLERR, + "UF3: Interaction {}-{}-{} was mapped to {}-{}-{}, but " + "potential interaction for {}-{}-{} was not found in " + "{} file", + i, j, k, i_mapped_to, j_mapped_to, k_mapped_to, + i_mapped_to, j_mapped_to, k_mapped_to, potf_name); + + + cut_3b_list[i][j] = std::max(cut_3b_list[i_mapped_to][j_mapped_to], + cut_3b_list[i][j]); + + + cut_3b[i][j][k] = cut_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + + knot_spacing_type_3b[i][j][k] = + knot_spacing_type_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + + int key = map_3b[i][j][k]; + int mapped_to_key = map_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + + n3b_knots_array_size[key][0] = n3b_knots_array_size[mapped_to_key][0]; + n3b_knots_array_size[key][1] = n3b_knots_array_size[mapped_to_key][1]; + n3b_knots_array_size[key][2] = n3b_knots_array_size[mapped_to_key][2]; + + n3b_coeff_array_size[key][0] = n3b_coeff_array_size[mapped_to_key][0]; + n3b_coeff_array_size[key][1] = n3b_coeff_array_size[mapped_to_key][1]; + n3b_coeff_array_size[key][2] = n3b_coeff_array_size[mapped_to_key][2]; + + min_cut_3b[i][j][k][0] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][0];//n3b_knots_array[key][0][0]; + + min_cut_3b[i][j][k][1] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][1];//n3b_knots_array[key][1][0]; + + min_cut_3b[i][j][k][2] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][2];//n3b_knots_array[key][2][0]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][0]; knot_no++) + n3b_knots_array[key][0][knot_no] = n3b_knots_array[mapped_to_key][0][knot_no]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][1]; knot_no++) + n3b_knots_array[key][1][knot_no] = n3b_knots_array[mapped_to_key][1][knot_no]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][2]; knot_no++) + n3b_knots_array[key][2][knot_no] = n3b_knots_array[mapped_to_key][2][knot_no]; + + for (int coeff1 = 0; coeff1 < n3b_coeff_array_size[key][0]; coeff1++) + for (int coeff2 = 0; coeff2 < n3b_coeff_array_size[key][1]; coeff2++) + for (int coeff3 = 0; coeff3 < n3b_coeff_array_size[key][2]; coeff3++) + n3b_coeff_array[key][coeff1][coeff2][coeff3] = + n3b_coeff_array[mapped_to_key][coeff1][coeff2][coeff3]; + setflag_3b[i][j][k] = 1; + } + } + } + } } } @@ -826,7 +1689,7 @@ void PairUF3::create_bsplines() if (setflag[i][j] != 1) error->all(FLERR, "UF3: Not all 2-body UF potentials are set, " - "missing potential file for {}-{} interaction", + "missing potential for {}-{} interaction", i, j); } } @@ -837,7 +1700,7 @@ void PairUF3::create_bsplines() if (setflag_3b[i][j][k] != 1) error->all(FLERR, "UF3: Not all 3-body UF potentials are set, " - "missing potential file for {}-{}-{} interaction", + "missing potential for {}-{}-{} interaction", i, j, k); } } @@ -846,20 +1709,41 @@ void PairUF3::create_bsplines() for (int i = 1; i < num_of_elements + 1; i++) { for (int j = i; j < num_of_elements + 1; j++) { - uf3_impl->UFBS2b[i][j] = + /*uf3_impl->UFBS2b[i][j] = uf3_pair_bspline(lmp, uf3_impl->n2b_knot[i][j], uf3_impl->n2b_coeff[i][j], - knot_spacing_type_2b[i][j]); + knot_spacing_type_2b[i][j]);*/ + + uf3_impl->UFBS2b[i][j] = uf3_pair_bspline(lmp, n2b_knots_array[i][j], + n2b_knots_array_size[i][j], + n2b_coeff_array[i][j], + n2b_coeff_array_size[i][j], + knot_spacing_type_2b[i][j]); uf3_impl->UFBS2b[j][i] = uf3_impl->UFBS2b[i][j]; } if (pot_3b) { for (int j = 1; j < num_of_elements + 1; j++) { for (int k = j; k < num_of_elements + 1; k++) { - std::string key = std::to_string(i) + std::to_string(j) + std::to_string(k); + /*std::string key = std::to_string(i) + std::to_string(j) + std::to_string(k); + uf3_impl->UFBS3b[i][j][k] = uf3_triplet_bspline( + lmp, uf3_impl->n3b_knot_matrix[i][j][k], uf3_impl->n3b_coeff_matrix[key], knot_spacing_type_3b[i][j][k]);*/ + int key = map_3b[i][j][k]; + int key2 = map_3b[i][k][j]; + /*utils::logmesg(lmp, "Setting UFBS3b for {}-{}-{} map_3b={} and for {}-{}-{} " + "map_3b={}\n", i, j, k, key, i, k, j, + key2);*/ uf3_impl->UFBS3b[i][j][k] = uf3_triplet_bspline( - lmp, uf3_impl->n3b_knot_matrix[i][j][k], uf3_impl->n3b_coeff_matrix[key], knot_spacing_type_3b[i][j][k]); - std::string key2 = std::to_string(i) + std::to_string(k) + std::to_string(j); + lmp, n3b_knots_array[key], n3b_knots_array_size[key], + n3b_coeff_array[key], n3b_coeff_array_size[key], + knot_spacing_type_3b[i][j][k]); + + /*std::string key2 = std::to_string(i) + std::to_string(k) + std::to_string(j); uf3_impl->UFBS3b[i][k][j] = uf3_triplet_bspline( - lmp, uf3_impl->n3b_knot_matrix[i][k][j], uf3_impl->n3b_coeff_matrix[key2], knot_spacing_type_3b[i][k][j]); + lmp, uf3_impl->n3b_knot_matrix[i][k][j], uf3_impl->n3b_coeff_matrix[key2], knot_spacing_type_3b[i][k][j]);*/ + //int key2 = map_3b[i][k][j]; + uf3_impl->UFBS3b[i][k][j] = uf3_triplet_bspline( + lmp, n3b_knots_array[key2], n3b_knots_array_size[key2], + n3b_coeff_array[key2], n3b_coeff_array_size[key2], + knot_spacing_type_3b[i][k][j]); } } } @@ -1172,7 +2056,23 @@ double PairUF3::memory_usage() bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * 3 * sizeof(double); //min_cut_3b - for (int i = 1; i < num_of_elements + 1; i++) { + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //n2b_knots_array_size + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //n2b_coeff_array_size + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_knots_2b * + sizeof(double); //n2b_knots_array + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_coeff_2b * + sizeof(double); //n2b_coeff_array + + if (pot_3b) { + bytes += (double) tot_interaction_count_3b * 3 * sizeof(double); //n3b_knots_array_size + bytes += (double) tot_interaction_count_3b * 3 * sizeof(double); //n3b_coeff_array_size + bytes += (double) tot_interaction_count_3b * 3 * max_num_knots_3b * sizeof(double); //n3b_knots_array + bytes += (double) tot_interaction_count_3b * max_num_coeff_3b * max_num_coeff_3b * + max_num_coeff_3b * sizeof(double); //n3b_coeff_array + } + /*for (int i = 1; i < num_of_elements + 1; i++) { for (int j = i; j < num_of_elements + 1; j++) { bytes += (double) 2 * uf3_impl->n2b_knot[i][j].size() * sizeof(double); //n2b_knot bytes += (double) 2 * uf3_impl->n2b_coeff[i][j].size() * sizeof(double); //n2b_coeff @@ -1196,7 +2096,7 @@ double PairUF3::memory_usage() } } } - } + }*/ for (int i = 1; i < num_of_elements + 1; i++) { for (int j = i; j < num_of_elements + 1; j++) { diff --git a/src/ML-UF3/pair_uf3.h b/src/ML-UF3/pair_uf3.h index 293d359c3fe..82ce7160422 100644 --- a/src/ML-UF3/pair_uf3.h +++ b/src/ML-UF3/pair_uf3.h @@ -49,6 +49,8 @@ class PairUF3 : public Pair { void uf3_read_pot_file(char *potf_name); void uf3_read_pot_file(int i, int j, char *potf_name); void uf3_read_pot_file(int i, int j, int k, char *potf_name); + void uf3_read_unified_pot_file(char *potf_name); + void communicate(); int nbody_flag, n2body_pot_files, n3body_pot_files, tot_pot_files; int bsplines_created; bool pot_3b; @@ -59,6 +61,26 @@ class PairUF3 : public Pair { struct UF3Impl *uf3_impl; //PIMPLE (pointer-to-implementation) UF3Impl *get_UF3Impl(); + int max_num_knots_2b = 0; + int max_num_coeff_2b = 0; + int max_num_knots_3b = 0; + int max_num_coeff_3b = 0; + double ***n2b_knots_array, ***n2b_coeff_array; + int **n2b_knots_array_size, **n2b_coeff_array_size; + + int ***map_3b, tot_interaction_count_3b; + double ***n3b_knots_array, ****n3b_coeff_array; + int **n3b_knots_array_size, **n3b_coeff_array_size; + + /*void uf3_read_2b_pot_block(int itype, int jtype, std::string iele, + std::string jele, + TextFileReader &txtfilereader); + + void uf3_read_3b_pot_block(int itype, int jtype, int ktype, + std::string iele, std::string jele, + std::string kele, + TextFileReader &txtfilereader);*/ + //Accessor function called by pair_uf3_kokkos.cpp //Will probably be removed once std::vector are converted to arrays std::vector>>& get_n2b_knot(); From cf729fc358fc96be2ee1eed622d32fded730b775 Mon Sep 17 00:00:00 2001 From: Ajinkya Hire Date: Mon, 15 Apr 2024 10:38:00 -0400 Subject: [PATCH 2/6] Added new constructor functions in uf3_pair_bspline and uf3_triplet_bspline to construct std::vectors of knots and coefficients rom memory block --- src/ML-UF3/uf3_pair_bspline.cpp | 56 +++++++++++ src/ML-UF3/uf3_pair_bspline.h | 7 ++ src/ML-UF3/uf3_triplet_bspline.cpp | 147 +++++++++++++++++++++++++++++ src/ML-UF3/uf3_triplet_bspline.h | 5 + 4 files changed, 215 insertions(+) diff --git a/src/ML-UF3/uf3_pair_bspline.cpp b/src/ML-UF3/uf3_pair_bspline.cpp index 3ecdb2f626f..1e8e2eeffaf 100644 --- a/src/ML-UF3/uf3_pair_bspline.cpp +++ b/src/ML-UF3/uf3_pair_bspline.cpp @@ -78,6 +78,62 @@ uf3_pair_bspline::uf3_pair_bspline(LAMMPS *ulmp, const std::vector &ukno dnbspline_bases.push_back(uf3_bspline_basis2(lmp, &dnknot_vect[i], dncoeff_vect[i])); } +// Constructor +// Passing arrays +uf3_pair_bspline::uf3_pair_bspline(LAMMPS *ulmp, const double* uknot_array, + const int uknot_array_size, + const double* ucoeff_array, + const int ucoeff_array_size, + const int uknot_spacing_type) +{ + lmp = ulmp; + + knot_vect = std::vector (uknot_array, uknot_array + uknot_array_size); + coeff_vect = std::vector (ucoeff_array, ucoeff_array + ucoeff_array_size); + + knot_spacing_type = uknot_spacing_type; + if (knot_spacing_type==0){ + knot_spacing = knot_vect[4]-knot_vect[3]; + get_starting_index=&uf3_pair_bspline::get_starting_index_uniform; + } + else if (knot_spacing_type==1){ + knot_spacing = 0; + get_starting_index=&uf3_pair_bspline::get_starting_index_nonuniform; + } + + else + lmp->error->all(FLERR, "UF3: Expected either '0'(uniform-knots) or \n\ + '1'(non-uniform knots)"); + + knot_vect_size = uknot_array_size; + coeff_vect_size = ucoeff_array_size; + + // Initialize B-Spline Basis Functions + for (int i = 0; i < knot_vect.size() - 4; i++) + bspline_bases.push_back(uf3_bspline_basis3(lmp, &knot_vect[i], coeff_vect[i])); + + // Initialize Coefficients and Knots for Derivatives + // The last coefficient needs to be droped + for (int i = 0; i < coeff_vect_size - 1; i++) { + double dntemp4 = 3 / (knot_vect[i + 4] - knot_vect[i + 1]); + dncoeff_vect.push_back((coeff_vect[i + 1] - coeff_vect[i]) * dntemp4); + } + //What we have is a clamped bspline -->i.e value of the bspline curve at the + //knots with multiplicity equal to the degree of bspline is equal to the coefficient + // + //Therefore for the derivative bspline the very first and last knot needs to be droped + //to change their multiplicity from 4 (necessary condition for clamped cubic bspline) + //to 3 (necessary condition for clamped quadratic bspline) + // + //Also if the coeff vector size of decreases by 1 for the derivative bspline + //knots size needs to go down by 2 as ==> knots = coefficient + degree + 1 + for (int i = 1; i < knot_vect_size - 1; i++) dnknot_vect.push_back(knot_vect[i]); + + // Initialize B-Spline Derivative Basis Functions + for (int i = 0; i < dnknot_vect.size() - 3; i++) + dnbspline_bases.push_back(uf3_bspline_basis2(lmp, &dnknot_vect[i], dncoeff_vect[i])); +} + uf3_pair_bspline::~uf3_pair_bspline() {} int uf3_pair_bspline::get_starting_index_uniform(double r) diff --git a/src/ML-UF3/uf3_pair_bspline.h b/src/ML-UF3/uf3_pair_bspline.h index d10bfb430e0..e471f02ac4b 100644 --- a/src/ML-UF3/uf3_pair_bspline.h +++ b/src/ML-UF3/uf3_pair_bspline.h @@ -41,6 +41,13 @@ class uf3_pair_bspline { uf3_pair_bspline(LAMMPS *ulmp, const std::vector &uknot_vect, const std::vector &ucoeff_vect, const int &uknot_spacing_type); + + uf3_pair_bspline(LAMMPS *ulmp, const double* uknot_array, + const int uknot_array_size, + const double* ucoeff_array, + const int ucoeff_array_size, + const int uknot_spacing_type); + ~uf3_pair_bspline(); int knot_spacing_type; double knot_spacing=0; diff --git a/src/ML-UF3/uf3_triplet_bspline.cpp b/src/ML-UF3/uf3_triplet_bspline.cpp index a2087bd3a19..05275999657 100644 --- a/src/ML-UF3/uf3_triplet_bspline.cpp +++ b/src/ML-UF3/uf3_triplet_bspline.cpp @@ -145,6 +145,153 @@ uf3_triplet_bspline::uf3_triplet_bspline( } } +// Construct a new 3D B-Spline from arrays +uf3_triplet_bspline::uf3_triplet_bspline( + LAMMPS *ulmp, double **uknot_array, const int *uknot_array_size, + double ***ucoeff_array, const int *ucoeff_array_size, + const int &uknot_spacing_type) +{ + lmp = ulmp; + + knot_matrix.resize(3); + //utils::logmesg(lmp, "knot_matrix dim = {} {} {}\nknots = ",uknot_array_size[0], + // uknot_array_size[1], uknot_array_size[2]); + for (int i = 0; i < 3; i++) { + knot_matrix[i].resize(uknot_array_size[i]); + //utils::logmesg(lmp, "{}= ",i); + for (int j = 0; j < uknot_array_size[i]; j++) { + //utils::logmesg(lmp, "{} ", uknot_array[i][j]); + knot_matrix[i][j] = uknot_array[i][j]; + } + //utils::logmesg(lmp,"\n"); + } + + coeff_matrix.resize(ucoeff_array_size[0]); + for (int i = 0; i < ucoeff_array_size[0]; i++) { + coeff_matrix[i].resize(ucoeff_array_size[1]); + for (int j = 0; j < ucoeff_array_size[1]; j++) { + coeff_matrix[i][j].resize(ucoeff_array_size[2]); + for (int k = 0; k < ucoeff_array_size[2]; k++){ + coeff_matrix[i][j][k] = ucoeff_array[i][j][k]; + } + } + } + + knot_spacing_type = uknot_spacing_type; + if (knot_spacing_type==0){ + knot_spacing_ij = knot_matrix[2][4]-knot_matrix[2][3]; + knot_spacing_ik = knot_matrix[1][4]-knot_matrix[1][3]; + knot_spacing_jk = knot_matrix[0][4]-knot_matrix[0][3]; + get_starting_index=&uf3_triplet_bspline::get_starting_index_uniform; + } + else if (knot_spacing_type==1){ + knot_spacing_ij = 0; + knot_spacing_ik = 0; + knot_spacing_jk = 0; + get_starting_index=&uf3_triplet_bspline::get_starting_index_nonuniform; + } + + else + lmp->error->all(FLERR, "UF3: Expected either '0'(uniform-knots) or \n\ + '1'(non-uniform knots)"); + + knot_vect_size_ij = knot_matrix[2].size(); + knot_vect_size_ik = knot_matrix[1].size(); + knot_vect_size_jk = knot_matrix[0].size(); + + int resolution_ij = knot_vect_size_ij - 4; + int resolution_ik = knot_vect_size_ik - 4; + int resolution_jk = knot_vect_size_jk - 4; + + // Cache Spline Basis Functions + for (int l = 0; l < resolution_ij; l++) { + bsplines_ij.push_back(uf3_bspline_basis3(lmp, &knot_matrix[2][l], 1)); + } + + for (int l = 0; l < resolution_ik; l++) { + // Reuse jk Basis if Knots match + if (knot_matrix[1][l] == knot_matrix[2][l] && knot_matrix[1][l + 1] == knot_matrix[2][l + 1] && + knot_matrix[1][l + 2] == knot_matrix[2][l + 2] && + knot_matrix[1][l + 3] == knot_matrix[2][l + 3]) + bsplines_ik.push_back(bsplines_ij[l]); + else + bsplines_ik.push_back(uf3_bspline_basis3(lmp, &knot_matrix[1][l], 1)); + } + + for (int l = 0; l < resolution_jk; l++) { + bsplines_jk.push_back(uf3_bspline_basis3(lmp, &knot_matrix[0][l], 1)); + } + + // Initialize Coefficients for Derivatives + for (int i = 0; i < coeff_matrix.size(); i++) { + std::vector> dncoeff_vect2; + for (int j = 0; j < coeff_matrix[0].size(); j++) { + std::vector dncoeff_vect; + for (int k = 0; k < coeff_matrix[0][0].size() - 1; k++) { + double dntemp4 = 3 / (knot_matrix[0][k + 4] - knot_matrix[0][k + 1]); + dncoeff_vect.push_back((coeff_matrix[i][j][k + 1] - coeff_matrix[i][j][k]) * dntemp4); + } + dncoeff_vect2.push_back(dncoeff_vect); + } + dncoeff_matrix_jk.push_back(dncoeff_vect2); + } + + for (int i = 0; i < coeff_matrix.size(); i++) { + std::vector> dncoeff_vect2; + for (int j = 0; j < coeff_matrix[0].size() - 1; j++) { + double dntemp4 = 3 / (knot_matrix[1][j + 4] - knot_matrix[1][j + 1]); + std::vector dncoeff_vect; + for (int k = 0; k < coeff_matrix[0][0].size(); k++) { + dncoeff_vect.push_back((coeff_matrix[i][j + 1][k] - coeff_matrix[i][j][k]) * dntemp4); + } + dncoeff_vect2.push_back(dncoeff_vect); + } + dncoeff_matrix_ik.push_back(dncoeff_vect2); + } + + for (int i = 0; i < coeff_matrix.size() - 1; i++) { + std::vector> dncoeff_vect2; + double dntemp4 = 3 / (knot_matrix[2][i + 4] - knot_matrix[2][i + 1]); + for (int j = 0; j < coeff_matrix[0].size(); j++) { + std::vector dncoeff_vect; + for (int k = 0; k < coeff_matrix[0][0].size(); k++) { + dncoeff_vect.push_back((coeff_matrix[i + 1][j][k] - coeff_matrix[i][j][k]) * dntemp4); + } + dncoeff_vect2.push_back(dncoeff_vect); + } + dncoeff_matrix_ij.push_back(dncoeff_vect2); + } + + std::vector> dnknot_matrix; + for (int i = 0; i < knot_matrix.size(); i++) { + std::vector dnknot_vect; + for (int j = 1; j < knot_matrix[0].size() - 1; j++) { + dnknot_vect.push_back(knot_matrix[i][j]); + } + dnknot_matrix.push_back(dnknot_vect); + } + + // Cache Derivative Spline Basis Functions + for (int l = 0; l < resolution_ij - 1; l++) { + dnbsplines_ij.push_back(uf3_bspline_basis2(lmp, &dnknot_matrix[2][l], 1)); + } + + for (int l = 0; l < resolution_ik - 1; l++) { + // Reuse jk Basis if Knots match + if (dnknot_matrix[1][l] == dnknot_matrix[2][l] && + dnknot_matrix[1][l + 1] == dnknot_matrix[2][l + 1] && + dnknot_matrix[1][l + 2] == dnknot_matrix[2][l + 2]) + dnbsplines_ik.push_back(dnbsplines_ij[l]); + else + dnbsplines_ik.push_back(uf3_bspline_basis2(lmp, &dnknot_matrix[1][l], 1)); + } + + for (int l = 0; l < resolution_jk - 1; l++) { + dnbsplines_jk.push_back(uf3_bspline_basis2(lmp, &dnknot_matrix[0][l], 1)); + } +} + + // Destructor uf3_triplet_bspline::~uf3_triplet_bspline() {} diff --git a/src/ML-UF3/uf3_triplet_bspline.h b/src/ML-UF3/uf3_triplet_bspline.h index 642201d8790..e627a61f9ed 100644 --- a/src/ML-UF3/uf3_triplet_bspline.h +++ b/src/ML-UF3/uf3_triplet_bspline.h @@ -47,6 +47,11 @@ class uf3_triplet_bspline { uf3_triplet_bspline(LAMMPS *ulmp, const std::vector> &uknot_matrix, const std::vector>> &ucoeff_matrix, const int &uknot_spacing_type); + + uf3_triplet_bspline(LAMMPS *ulmp, double **uknot_array, const int *uknot_array_size, + double ***ucoeff_array, const int *ucoeff_array_size, + const int &uknot_spacing_type); + ~uf3_triplet_bspline(); int knot_spacing_type; double knot_spacing_ij=0,knot_spacing_ik=0,knot_spacing_jk=0; From f6c8bd117869d3379358eb59ec476f162a0f2ca1 Mon Sep 17 00:00:00 2001 From: Ajinkya Hire Date: Mon, 15 Apr 2024 10:51:39 -0400 Subject: [PATCH 3/6] Updated pair_coeff in unittest to read only one potential file; added Nb.uf3 unified potential file --- potentials/{Nb_Nb_Nb.uf3 => Nb.uf3} | 9 ++++++++- potentials/Nb_Nb.uf3 | 7 ------- unittest/force-styles/tests/manybody-pair-uf3.yaml | 3 +-- 3 files changed, 9 insertions(+), 10 deletions(-) rename potentials/{Nb_Nb_Nb.uf3 => Nb.uf3} (95%) delete mode 100644 potentials/Nb_Nb.uf3 diff --git a/potentials/Nb_Nb_Nb.uf3 b/potentials/Nb.uf3 similarity index 95% rename from potentials/Nb_Nb_Nb.uf3 rename to potentials/Nb.uf3 index ac3748b33cb..5f1cdb6f63c 100644 --- a/potentials/Nb_Nb_Nb.uf3 +++ b/potentials/Nb.uf3 @@ -1,5 +1,12 @@ #UF3 POT UNITS: metal DATE: 2024-04-02 12:18:15.359106 AUTHOR: Ajinkya_Hire CITATION: -3B 0 3 nk +2B Nb Nb 0 3 nk +8.0 31 +0.001 0.001 0.001 0.001 0.33429166666666665 0.66758333333333331 1.000875 1.3341666666666665 1.6674583333333333 2.00075 2.3340416666666663 2.6673333333333331 3.0006249999999999 3.3339166666666666 3.667208333333333 4.0004999999999997 4.3337916666666665 4.6670833333333333 5.000375 5.3336666666666668 5.6669583333333335 6.0002500000000003 6.3335416666666671 6.6668333333333338 7.0001249999999997 7.3334166666666665 7.6667083333333332 8 8 8 8 +27 +79.140244588519465 79.140244588519465 55.85833391113556 36.597903318706138 21.358952811231141 12.290000872768841 1.9593931914091953 -0.65697974623243804 -0.85177956270573463 -0.68929688239869991 -0.46787243412973262 -0.27624655899523165 -0.11912921944351409 -0.056302369393035338 -0.0049812809608429064 0.0085637634684603507 0.0034716161454604712 -0.0058751075573311978 -0.005453415412748467 -0.0015123194244718201 0.0011577919587182201 0.001583772506713282 -0.00049823976100720228 -0.0013902809146717273 0 0 0 +# +#UF3 POT UNITS: metal DATE: 2024-04-02 12:18:15.359106 AUTHOR: Ajinkya_Hire CITATION: +3B Nb Nb Nb 0 3 nk 8.0 4.0 4.0 23 15 15 0.001 0.001 0.001 0.001 0.50093749999999992 1.000875 1.5008124999999999 2.00075 2.5006874999999997 3.0006249999999999 3.5005624999999996 4.0004999999999997 4.5004375000000003 5.000375 5.5003124999999997 6.0002500000000003 6.5001875 7.0001249999999997 7.5000625000000003 8 8 8 8 0.001 0.001 0.001 0.001 0.50087499999999996 1.00075 1.5006249999999999 2.0005000000000002 2.500375 3.0002499999999999 3.5001250000000002 4 4 4 4 diff --git a/potentials/Nb_Nb.uf3 b/potentials/Nb_Nb.uf3 deleted file mode 100644 index a8583b105d5..00000000000 --- a/potentials/Nb_Nb.uf3 +++ /dev/null @@ -1,7 +0,0 @@ -#UF3 POT UNITS: metal DATE: 2024-04-02 12:18:15.359106 AUTHOR: Ajinkya_Hire CITATION: -2B 0 3 nk -8.0 31 -0.001 0.001 0.001 0.001 0.33429166666666665 0.66758333333333331 1.000875 1.3341666666666665 1.6674583333333333 2.00075 2.3340416666666663 2.6673333333333331 3.0006249999999999 3.3339166666666666 3.667208333333333 4.0004999999999997 4.3337916666666665 4.6670833333333333 5.000375 5.3336666666666668 5.6669583333333335 6.0002500000000003 6.3335416666666671 6.6668333333333338 7.0001249999999997 7.3334166666666665 7.6667083333333332 8 8 8 8 -27 -79.140244588519465 79.140244588519465 55.85833391113556 36.597903318706138 21.358952811231141 12.290000872768841 1.9593931914091953 -0.65697974623243804 -0.85177956270573463 -0.68929688239869991 -0.46787243412973262 -0.27624655899523165 -0.11912921944351409 -0.056302369393035338 -0.0049812809608429064 0.0085637634684603507 0.0034716161454604712 -0.0058751075573311978 -0.005453415412748467 -0.0015123194244718201 0.0011577919587182201 0.001583772506713282 -0.00049823976100720228 -0.0013902809146717273 0 0 0 -# diff --git a/unittest/force-styles/tests/manybody-pair-uf3.yaml b/unittest/force-styles/tests/manybody-pair-uf3.yaml index 075891e8f4c..534b489c782 100644 --- a/unittest/force-styles/tests/manybody-pair-uf3.yaml +++ b/unittest/force-styles/tests/manybody-pair-uf3.yaml @@ -14,8 +14,7 @@ post_commands: ! "" input_file: in.manybody pair_style: uf3 3 pair_coeff: ! | - * * Nb_Nb.uf3 - 3b * * * Nb_Nb_Nb.uf3 + * * Nb.uf3 Nb Nb Nb Nb Nb Nb Nb Nb extract: ! "" natoms: 64 init_vdwl: -76.14388662099438 From d468ee8f7dc462da6a852136b07175ae877df2a1 Mon Sep 17 00:00:00 2001 From: Ajinkya Hire Date: Mon, 15 Apr 2024 15:22:22 -0400 Subject: [PATCH 4/6] Updated the code as we are no longer using std::vector for knots and coefficients --- src/KOKKOS/pair_uf3_kokkos.cpp | 182 +++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 74 deletions(-) diff --git a/src/KOKKOS/pair_uf3_kokkos.cpp b/src/KOKKOS/pair_uf3_kokkos.cpp index 7bc6ef22d5a..5e0882d90bb 100644 --- a/src/KOKKOS/pair_uf3_kokkos.cpp +++ b/src/KOKKOS/pair_uf3_kokkos.cpp @@ -272,8 +272,8 @@ template void PairUF3Kokkos::create_coefficients( template void PairUF3Kokkos::create_2b_coefficients() { const int num_of_elements = atom->ntypes; - std::vector>>& n2b_knot = get_n2b_knot(); - std::vector>>& n2b_coeff = get_n2b_coeff(); + //std::vector>>& n2b_knot = get_n2b_knot(); + //std::vector>>& n2b_coeff = get_n2b_coeff(); // Setup interaction pair map //TODO: Instead of using map2b and map3b use simple indexing @@ -291,9 +291,9 @@ template void PairUF3Kokkos::create_2b_coefficien // Count max knots for array size - int max_knots = 0; - for (int i = 1; i < n2b_knot.size(); i++) - for (int j = i; j < n2b_knot[i].size(); j++) max_knots = max(max_knots, n2b_knot[i][j].size()); + int max_knots = max_num_knots_2b; + /*for (int i = 1; i < n2b_knot.size(); i++) + for (int j = i; j < n2b_knot[i].size(); j++) max_knots = max(max_knots, n2b_knot[i][j].size());*/ // Copy coefficients to view @@ -302,8 +302,9 @@ template void PairUF3Kokkos::create_2b_coefficien for (int i = 1; i < num_of_elements + 1; i++) { for (int j = i; j < num_of_elements + 1; j++) { - for (int k = 0; k < n2b_coeff[i][j].size(); k++) { - d_coefficients_2b_view(map2b_view(i, j), k) = n2b_coeff[i][j][k]; + for (int k = 0; k < max_num_coeff_2b; k++) { + //n2b_coeff[i][j].size(); k++) { + d_coefficients_2b_view(map2b_view(i, j), k) = n2b_coeff_array[i][j][k]; } } } @@ -318,10 +319,11 @@ template void PairUF3Kokkos::create_2b_coefficien for (int i = 1; i < num_of_elements + 1; i++) { for (int j = i; j < num_of_elements + 1; j++) { - for (int k = 0; k < n2b_knot[i][j].size(); k++) { - d_n2b_knot_view(map2b_view(i, j), k) = n2b_knot[i][j][k]; + for (int k = 0; k < max_num_knots_2b; k++) { + //n2b_knot[i][j].size(); k++) { + d_n2b_knot_view(map2b_view(i, j), k) = n2b_knots_array[i][j][k]; } - d_n2b_knot_spacings_view(map2b_view(i, j)) = get_knot_spacing_2b(i,j); + d_n2b_knot_spacings_view(map2b_view(i, j)) = n2b_knots_array[i][j][4] - n2b_knots_array[i][j][3];//get_knot_spacing_2b(i,j); } } @@ -334,8 +336,9 @@ template void PairUF3Kokkos::create_2b_coefficien for (int i = 1; i < num_of_elements + 1; i++) { for (int j = i; j < num_of_elements + 1; j++) { - for (int l = 0; l < n2b_knot[i][j].size() - 4; l++) { - auto c = get_constants(&n2b_knot[i][j][l], n2b_coeff[i][j][l]); + for (int l = 0; l < n2b_knots_array_size[i][j] - 4; l++) { + //n2b_knot[i][j].size() - 4; l++) { + auto c = get_constants(&n2b_knots_array[i][j][l], n2b_coeff_array[i][j][l]); for (int k = 0; k < 16; k++) constants_2b_view(map2b_view(i, j), l, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; @@ -349,10 +352,11 @@ template void PairUF3Kokkos::create_2b_coefficien for (int i = 1; i < num_of_elements + 1; i++) { for (int j = i; j < num_of_elements + 1; j++) { - for (int l = 0; l < n2b_knot[i][j].size() - 5; l++) { - double dntemp4 = 3 / (n2b_knot[i][j][l + 4] - n2b_knot[i][j][l + 1]); - double coeff = (n2b_coeff[i][j][l + 1] - n2b_coeff[i][j][l]) * dntemp4; - auto c = get_dnconstants(&n2b_knot[i][j][l + 1], coeff); + for (int l = 0; l < n2b_knots_array_size[i][j] - 5; l++) { + //n2b_knot[i][j].size() - 5; l++) { + double dntemp4 = 3 / (n2b_knots_array[i][j][l + 4] - n2b_knots_array[i][j][l + 1]); + double coeff = (n2b_coeff_array[i][j][l + 1] - n2b_coeff_array[i][j][l]) * dntemp4; + auto c = get_dnconstants(&n2b_knots_array[i][j][l + 1], coeff); for (int k = 0; k < 9; k++) dnconstants_2b_view(map2b_view(i, j), l, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; @@ -365,8 +369,8 @@ template void PairUF3Kokkos::create_2b_coefficien template void PairUF3Kokkos::create_3b_coefficients() { const int num_of_elements = atom->ntypes; - std::vector>>>>& n3b_knot_matrix = - get_n3b_knot_matrix(); + //std::vector>>>>& n3b_knot_matrix = + // get_n3b_knot_matrix(); //std::unordered_map>>>& // n3b_coeff_matrix = get_n3b_coeff_matrix(); // Init interaction map for 3B @@ -388,21 +392,21 @@ template void PairUF3Kokkos::create_3b_coefficien // Count max knots for view - int max_knots = 0; + int max_knots = max_num_knots_3b; //In n3b_knot_matrix[i][j][k], //n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, //n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, //n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, //see pair_uf3.cpp for more details - for (int i = 1; i < n3b_knot_matrix.size(); i++) + /*for (int i = 1; i < n3b_knot_matrix.size(); i++) for (int j = 1; j < n3b_knot_matrix[i].size(); j++) for (int k = 1; k < n3b_knot_matrix[i][j].size(); k++) max_knots = max(max_knots, max(n3b_knot_matrix[i][j][k][0].size(), max(n3b_knot_matrix[i][j][k][1].size(), - n3b_knot_matrix[i][j][k][2].size()))); + n3b_knot_matrix[i][j][k][2].size())));*/ // Init knot matrix view @@ -411,21 +415,27 @@ template void PairUF3Kokkos::create_3b_coefficien auto d_n3b_knot_matrix_view = Kokkos::create_mirror(d_n3b_knot_matrix); auto d_n3b_knot_matrix_spacings_view = Kokkos::create_mirror(d_n3b_knot_matrix_spacings); - for (int i = 1; i < n3b_knot_matrix.size(); i++) - for (int j = 1; j < n3b_knot_matrix[i].size(); j++) - for (int k = 1; k < n3b_knot_matrix[i][j].size(); k++) { - for (int m = 0; m < n3b_knot_matrix[i][j][k][0].size(); m++) - d_n3b_knot_matrix_view(map3b_view(i, j, k), 0, m) = n3b_knot_matrix[i][j][k][0][m]; - for (int m = 0; m < n3b_knot_matrix[i][j][k][1].size(); m++) - d_n3b_knot_matrix_view(map3b_view(i, j, k), 1, m) = n3b_knot_matrix[i][j][k][1][m]; - for (int m = 0; m < n3b_knot_matrix[i][j][k][2].size(); m++) - d_n3b_knot_matrix_view(map3b_view(i, j, k), 2, m) = n3b_knot_matrix[i][j][k][2][m]; - - d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),2) = get_knot_spacing_3b_ij(i,j,k); + for (int i = 1; i < num_of_elements + 1; i++)//n3b_knot_matrix.size(); i++) + for (int j = 1; j < num_of_elements + 1; j++)//n3b_knot_matrix[i].size(); j++) + for (int k = 1; k < num_of_elements + 1; k++){//n3b_knot_matrix[i][j].size(); k++) { + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][0]; m++)//n3b_knot_matrix[i][j][k][0].size(); m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 0, m) = + n3b_knots_array[map_3b[i][j][k]][0][m];//n3b_knot_matrix[i][j][k][0][m]; + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][1]; m++)//n3b_knot_matrix[i][j][k][1].size(); m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 1, m) = + n3b_knots_array[map_3b[i][j][k]][1][m];//n3b_knot_matrix[i][j][k][1][m]; + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][2]; m++)//n3b_knot_matrix[i][j][k][2].size(); m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 2, m) = + n3b_knots_array[map_3b[i][j][k]][2][m];//n3b_knot_matrix[i][j][k][2][m]; + + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),2) = + n3b_knots_array[map_3b[i][j][k]][2][4] - n3b_knots_array[map_3b[i][j][k]][2][3];//get_knot_spacing_3b_ij(i,j,k); //uf3_impl->UFBS3b[i][j][k].knot_spacing_ij; - d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),1) = get_knot_spacing_3b_ik(i,j,k); + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),1) = + n3b_knots_array[map_3b[i][j][k]][1][4] - n3b_knots_array[map_3b[i][j][k]][1][3];//get_knot_spacing_3b_ik(i,j,k); //uf3_impl->UFBS3b[i][j][k].knot_spacing_ik; - d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),0) = get_knot_spacing_3b_jk(i,j,k); + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),0) = + n3b_knots_array[map_3b[i][j][k]][0][4] - n3b_knots_array[map_3b[i][j][k]][0][3];//get_knot_spacing_3b_jk(i,j,k); //uf3_impl->UFBS3b[i][j][k].knot_spacing_jk; } Kokkos::deep_copy(d_n3b_knot_matrix, d_n3b_knot_matrix_view); @@ -440,11 +450,14 @@ template void PairUF3Kokkos::create_3b_coefficien for (int j = 1; j < num_of_elements + 1; j++) { for (int k = 1; k < num_of_elements + 1; k++) { d_n3b_knot_spacings_view(map3b_view(i, j, k), 0) = - 1 / (n3b_knot_matrix[i][j][k][0][5] - n3b_knot_matrix[i][j][k][0][4]); + 1 / (n3b_knots_array[map_3b[i][j][k]][0][5] - n3b_knots_array[map_3b[i][j][k]][0][4]); + //(n3b_knot_matrix[i][j][k][0][5] - n3b_knot_matrix[i][j][k][0][4]); d_n3b_knot_spacings_view(map3b_view(i, j, k), 1) = - 1 / (n3b_knot_matrix[i][j][k][1][5] - n3b_knot_matrix[i][j][k][1][4]); + 1 / (n3b_knots_array[map_3b[i][j][k]][1][5] - n3b_knots_array[map_3b[i][j][k]][1][4]); + //(n3b_knot_matrix[i][j][k][1][5] - n3b_knot_matrix[i][j][k][1][4]); d_n3b_knot_spacings_view(map3b_view(i, j, k), 2) = - 1 / (n3b_knot_matrix[i][j][k][2][5] - n3b_knot_matrix[i][j][k][2][4]); + 1 / (n3b_knots_array[map_3b[i][j][k]][2][5] - n3b_knots_array[map_3b[i][j][k]][2][4]); + //(n3b_knot_matrix[i][j][k][2][5] - n3b_knot_matrix[i][j][k][2][4]); } } } @@ -459,14 +472,14 @@ template void PairUF3Kokkos::create_3b_coefficien for (int n = 1; n < num_of_elements + 1; n++) { for (int m = 1; m < num_of_elements + 1; m++) { for (int o = 1; o < num_of_elements + 1; o++) { - std::string key = std::to_string(n) + std::to_string(m) + std::to_string(o); - std::vector>> n3b_coeff_matrix_key = - get_n3b_coeff_matrix_key(key); - for (int i = 0; i < n3b_coeff_matrix_key.size(); i++) { - for (int j = 0; j < n3b_coeff_matrix_key[i].size(); j++) { - for (int k = 0; k < n3b_coeff_matrix_key[i][j].size() - 1; k++) { + //std::string key = std::to_string(n) + std::to_string(m) + std::to_string(o); + //std::vector>> n3b_coeff_matrix_key = + // get_n3b_coeff_matrix_key(key); + for (int i = 0; i < n3b_coeff_array_size[map_3b[n][m][o]][0]; i++) {//n3b_coeff_matrix_key.size(); i++) { + for (int j = 0; j < n3b_coeff_array_size[map_3b[n][m][o]][1]; j++) {//n3b_coeff_matrix_key[i].size(); j++) { + for (int k = 0; k < n3b_coeff_array_size[map_3b[n][m][o]][2]; k++) {//n3b_coeff_matrix_key[i][j].size() - 1; k++) { d_coefficients_3b_view(map3b_view(n, m, o), i, j, k) = - n3b_coeff_matrix_key[i][j][k]; + n3b_coeff_array[map_3b[n][m][o]][i][j][k];//n3b_coeff_matrix_key[i][j][k]; } } } @@ -497,40 +510,49 @@ template void PairUF3Kokkos::create_3b_coefficien for (int n = 1; n < num_of_elements + 1; n++) { for (int m = 1; m < num_of_elements + 1; m++) { for (int o = 1; o < num_of_elements + 1; o++) { - std::string key = std::to_string(n) + std::to_string(m) + std::to_string(o); - std::vector>> n3b_coeff_matrix_key = - get_n3b_coeff_matrix_key(key); - for (int i = 0; i < n3b_coeff_matrix_key.size(); i++) { - for (int j = 0; j < n3b_coeff_matrix_key[i].size(); j++) { - for (int k = 0; k < n3b_coeff_matrix_key[i][j].size() - 1; k++) { + //std::string key = std::to_string(n) + std::to_string(m) + std::to_string(o); + //std::vector>> n3b_coeff_matrix_key = + // get_n3b_coeff_matrix_key(key); + int coeff_dim1 = n3b_coeff_array_size[map_3b[n][m][o]][0]; + int coeff_dim2 = n3b_coeff_array_size[map_3b[n][m][o]][1]; + int coeff_dim3 = n3b_coeff_array_size[map_3b[n][m][o]][2]; + for (int i = 0; i < coeff_dim1; i++) {//n3b_coeff_matrix_key.size(); i++) { + for (int j = 0; j < coeff_dim2; j++) {//n3b_coeff_matrix_key[i].size(); j++) { + for (int k = 0; k < coeff_dim3; k++) {//n3b_coeff_matrix_key[i][j].size() - 1; k++) { F_FLOAT dntemp4 = - 3 / (n3b_knot_matrix[n][m][o][0][k + 4] - n3b_knot_matrix[n][m][o][0][k + 1]); + 3 / (n3b_knots_array[map_3b[n][m][o]][0][k + 4] - n3b_knots_array[map_3b[n][m][o]][0][k + 1]); + //(n3b_knot_matrix[n][m][o][0][k + 4] - n3b_knot_matrix[n][m][o][0][k + 1]); d_dncoefficients_3b_view(map3b_view(n, m, o), 2, i, j, k) = - (n3b_coeff_matrix_key[i][j][k + 1] - n3b_coeff_matrix_key[i][j][k]) * dntemp4; + (n3b_coeff_array[map_3b[n][m][o]][i][j][k + 1] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + //(n3b_coeff_matrix_key[i][j][k + 1] - n3b_coeff_matrix_key[i][j][k]) * dntemp4; } } } - for (int i = 0; i < n3b_coeff_matrix_key.size(); i++) { + for (int i = 0; i < coeff_dim1; i++) {//n3b_coeff_matrix_key.size(); i++) { std::vector> dncoeff_vect2; - for (int j = 0; j < n3b_coeff_matrix_key[i].size() - 1; j++) { + for (int j = 0; j < coeff_dim2; j++) {//n3b_coeff_matrix_key[i].size() - 1; j++) { F_FLOAT dntemp4 = - 3 / (n3b_knot_matrix[n][m][o][1][j + 4] - n3b_knot_matrix[n][m][o][1][j + 1]); + 3 / (n3b_knots_array[map_3b[n][m][o]][1][j + 4] - n3b_knots_array[map_3b[n][m][o]][1][j + 1]); + //(n3b_knot_matrix[n][m][o][1][j + 4] - n3b_knot_matrix[n][m][o][1][j + 1]); std::vector dncoeff_vect; - for (int k = 0; k < n3b_coeff_matrix_key[i][j].size(); k++) { + for (int k = 0; k < coeff_dim3; k++) {//n3b_coeff_matrix_key[i][j].size(); k++) { d_dncoefficients_3b_view(map3b_view(n, m, o), 1, i, j, k) = - (n3b_coeff_matrix_key[i][j + 1][k] - n3b_coeff_matrix_key[i][j][k]) * dntemp4; + (n3b_coeff_array[map_3b[n][m][o]][i][j + 1][k] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + //(n3b_coeff_matrix_key[i][j + 1][k] - n3b_coeff_matrix_key[i][j][k]) * dntemp4; } } } - for (int i = 0; i < n3b_coeff_matrix_key.size() - 1; i++) { + for (int i = 0; i < coeff_dim1; i++) {//n3b_coeff_matrix_key.size() - 1; i++) { F_FLOAT dntemp4 = - 3 / (n3b_knot_matrix[n][m][o][2][i + 4] - n3b_knot_matrix[n][m][o][2][i + 1]); - for (int j = 0; j < n3b_coeff_matrix_key[i].size(); j++) { - for (int k = 0; k < n3b_coeff_matrix_key[i][j].size(); k++) { + 3 / (n3b_knots_array[map_3b[n][m][o]][2][i + 4] - n3b_knots_array[map_3b[n][m][o]][2][i + 1]); + //(n3b_knot_matrix[n][m][o][2][i + 4] - n3b_knot_matrix[n][m][o][2][i + 1]); + for (int j = 0; j < coeff_dim2; j++) {//n3b_coeff_matrix_key[i].size(); j++) { + for (int k = 0; k < coeff_dim3; k++) {//n3b_coeff_matrix_key[i][j].size(); k++) { d_dncoefficients_3b_view(map3b_view(n, m, o), 0, i, j, k) = - (n3b_coeff_matrix_key[i + 1][j][k] - n3b_coeff_matrix_key[i][j][k]) * dntemp4; + (n3b_coeff_array[map_3b[n][m][o]][i + 1][j][k] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + //(n3b_coeff_matrix_key[i + 1][j][k] - n3b_coeff_matrix_key[i][j][k]) * dntemp4; } } } @@ -552,20 +574,26 @@ template void PairUF3Kokkos::create_3b_coefficien for (int n = 1; n < num_of_elements + 1; n++) { for (int m = 1; m < num_of_elements + 1; m++) { for (int o = 1; o < num_of_elements + 1; o++) { - for (int l = 0; l < n3b_knot_matrix[n][m][o][2].size() - 4; l++) { - auto c = get_constants(&n3b_knot_matrix[n][m][o][2][l], 1); + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][2] - 4; l++) { + //n3b_knot_matrix[n][m][o][2].size() - 4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][2][l], 1); + //auto c = get_constants(&n3b_knot_matrix[n][m][o][2][l], 1); for (int k = 0; k < 16; k++) constants_3b_view(map3b_view(n, m, o), 0, l, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; } - for (int l = 0; l < n3b_knot_matrix[n][m][o][1].size() - 4; l++) { - auto c = get_constants(&n3b_knot_matrix[n][m][o][1][l], 1); + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][1] - 4; l++) { + //n3b_knot_matrix[n][m][o][1].size() - 4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][1][l], 1); + //auto c = get_constants(&n3b_knot_matrix[n][m][o][1][l], 1); for (int k = 0; k < 16; k++) constants_3b_view(map3b_view(n, m, o), 1, l, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; } - for (int l = 0; l < n3b_knot_matrix[n][m][o][0].size() - 4; l++) { - auto c = get_constants(&n3b_knot_matrix[n][m][o][0][l], 1); + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][0] -4; l++) { + //n3b_knot_matrix[n][m][o][0].size() - 4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][0][l], 1); + //auto c = get_constants(&n3b_knot_matrix[n][m][o][0][l], 1); for (int k = 0; k < 16; k++) constants_3b_view(map3b_view(n, m, o), 2, l, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; @@ -581,20 +609,26 @@ template void PairUF3Kokkos::create_3b_coefficien for (int n = 1; n < num_of_elements + 1; n++) { for (int m = 1; m < num_of_elements + 1; m++) { for (int o = 1; o < num_of_elements + 1; o++) { - for (int l = 1; l < n3b_knot_matrix[n][m][o][2].size() - 5; l++) { - auto c = get_dnconstants(&n3b_knot_matrix[n][m][o][2][l], 1); + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][2] - 5; l++) { + //n3b_knot_matrix[n][m][o][2].size() - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][2][l], 1); + //auto c = get_dnconstants(&n3b_knot_matrix[n][m][o][2][l], 1); for (int k = 0; k < 9; k++) dnconstants_3b_view(map3b_view(n, m, o), 0, l - 1, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; } - for (int l = 1; l < n3b_knot_matrix[n][m][o][1].size() - 5; l++) { - auto c = get_dnconstants(&n3b_knot_matrix[n][m][o][1][l], 1); + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][1] - 5; l++) { + //n3b_knot_matrix[n][m][o][1].size() - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][1][l], 1); + //auto c = get_dnconstants(&n3b_knot_matrix[n][m][o][1][l], 1); for (int k = 0; k < 9; k++) dnconstants_3b_view(map3b_view(n, m, o), 1, l - 1, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; } - for (int l = 1; l < n3b_knot_matrix[n][m][o][0].size() - 5; l++) { - auto c = get_dnconstants(&n3b_knot_matrix[n][m][o][0][l], 1); + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][0] - 5; l++) { + //n3b_knot_matrix[n][m][o][0].size() - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][0][l], 1); + //auto c = get_dnconstants(&n3b_knot_matrix[n][m][o][0][l], 1); for (int k = 0; k < 9; k++) dnconstants_3b_view(map3b_view(n, m, o), 2, l - 1, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; From 4c1be999fa8aebf264db7fe94f4cf0d095540e16 Mon Sep 17 00:00:00 2001 From: Ajinkya Hire Date: Mon, 15 Apr 2024 15:31:42 -0400 Subject: [PATCH 5/6] Removed reference to std::vector knots and coefficients; commented out getter functions --- src/ML-UF3/pair_uf3.cpp | 38 ++++++++++++++++++++------------------ src/ML-UF3/pair_uf3.h | 4 ++-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/ML-UF3/pair_uf3.cpp b/src/ML-UF3/pair_uf3.cpp index b6986d422fd..8e853ab35bc 100644 --- a/src/ML-UF3/pair_uf3.cpp +++ b/src/ML-UF3/pair_uf3.cpp @@ -39,9 +39,9 @@ namespace LAMMPS_NS{ struct UF3Impl { - std::vector>> n2b_knot, n2b_coeff; - std::vector>>>> n3b_knot_matrix; - std::unordered_map>>> n3b_coeff_matrix; + //std::vector>> n2b_knot, n2b_coeff; + //std::vector>>>> n3b_knot_matrix; + //std::unordered_map>>> n3b_coeff_matrix; std::vector> UFBS2b; std::vector>> UFBS3b; @@ -289,12 +289,12 @@ void PairUF3::allocate() "pair:n2b_coeff_array_size"); // Contains knot_vect of 2-body potential for type i and j - uf3_impl->n2b_knot.resize(num_of_elements + 1); - uf3_impl->n2b_coeff.resize(num_of_elements + 1); + //uf3_impl->n2b_knot.resize(num_of_elements + 1); + //uf3_impl->n2b_coeff.resize(num_of_elements + 1); uf3_impl->UFBS2b.resize(num_of_elements + 1); for (int i = 1; i < num_of_elements + 1; i++) { - uf3_impl->n2b_knot[i].resize(num_of_elements + 1); - uf3_impl->n2b_coeff[i].resize(num_of_elements + 1); + //uf3_impl->n2b_knot[i].resize(num_of_elements + 1); + //uf3_impl->n2b_coeff[i].resize(num_of_elements + 1); uf3_impl->UFBS2b[i].resize(num_of_elements + 1); } if (pot_3b) { @@ -345,13 +345,13 @@ void PairUF3::allocate() memory->create(n3b_coeff_array_size, tot_interaction_count_3b, 3, "pair:n3b_coeff_array_size"); - uf3_impl->n3b_knot_matrix.resize(num_of_elements + 1); + //uf3_impl->n3b_knot_matrix.resize(num_of_elements + 1); uf3_impl->UFBS3b.resize(num_of_elements + 1); for (int i = 1; i < num_of_elements + 1; i++) { - uf3_impl->n3b_knot_matrix[i].resize(num_of_elements + 1); + //uf3_impl->n3b_knot_matrix[i].resize(num_of_elements + 1); uf3_impl->UFBS3b[i].resize(num_of_elements + 1); for (int j = 1; j < num_of_elements + 1; j++) { - uf3_impl->n3b_knot_matrix[i][j].resize(num_of_elements + 1); + //uf3_impl->n3b_knot_matrix[i][j].resize(num_of_elements + 1); uf3_impl->UFBS3b[i][j].resize(num_of_elements + 1); } } @@ -1085,7 +1085,7 @@ void PairUF3::uf3_read_unified_pot_file(char *potf_name) } } -void PairUF3::uf3_read_pot_file(int itype, int jtype, char *potf_name) +/*void PairUF3::uf3_read_pot_file(int itype, int jtype, char *potf_name) { FILE *fp = utils::open_potential(potf_name, lmp, nullptr); if (!fp) @@ -1646,7 +1646,7 @@ void PairUF3::uf3_read_pot_file(char *potf_name) "UF3: {} file does not contain right words indicating whether it is 2 or 3 body potential", potf_name); fclose(fp); -} +}*/ /* ---------------------------------------------------------------------- init specific to this pair style @@ -2118,25 +2118,27 @@ double PairUF3::memory_usage() //Accessor function called by pair_uf3_kokkos.cpp //Will probably be removed once std::vector are converted to arrays -std::vector>>& PairUF3::get_n2b_knot() +/*std::vector>>& PairUF3::get_n2b_knot() { return uf3_impl->n2b_knot; -} - +}*/ +/* std::vector>>& PairUF3::get_n2b_coeff() { return uf3_impl->n2b_coeff; -} +}*/ //Accessor function called by pair_uf3_kokkos.cpp //Will probably be removed once std::vector are converted to arrays +/* std::vector>>>>& PairUF3::get_n3b_knot_matrix() { return uf3_impl->n3b_knot_matrix; -} +}*/ //Accessor function called by pair_uf3_kokkos.cpp //Will probably be removed once std::vector are converted to arrays +/* std::vector>>& PairUF3::get_n3b_coeff_matrix_key(std::string key) { @@ -2160,4 +2162,4 @@ double PairUF3::get_knot_spacing_3b_jk(int i, int j, int k) { return uf3_impl->UFBS3b[i][j][k].knot_spacing_jk; } - +*/ diff --git a/src/ML-UF3/pair_uf3.h b/src/ML-UF3/pair_uf3.h index 82ce7160422..4c70ab7efed 100644 --- a/src/ML-UF3/pair_uf3.h +++ b/src/ML-UF3/pair_uf3.h @@ -83,14 +83,14 @@ class PairUF3 : public Pair { //Accessor function called by pair_uf3_kokkos.cpp //Will probably be removed once std::vector are converted to arrays - std::vector>>& get_n2b_knot(); + /*std::vector>>& get_n2b_knot(); std::vector>>& get_n2b_coeff(); std::vector>>>>& get_n3b_knot_matrix(); std::vector>>& get_n3b_coeff_matrix_key(std::string key); double get_knot_spacing_2b(int i, int j); double get_knot_spacing_3b_ij(int i, int j, int k); double get_knot_spacing_3b_ik(int i, int j, int k); - double get_knot_spacing_3b_jk(int i, int j, int k); + double get_knot_spacing_3b_jk(int i, int j, int k);*/ int *neighshort, maxshort; // short neighbor list array for 3body interaction }; From 18ae98201b35dc93e7409c8512bbe40a09f885d6 Mon Sep 17 00:00:00 2001 From: Ajinkya Hire Date: Wed, 17 Apr 2024 10:51:21 -0400 Subject: [PATCH 6/6] Updated the documentation about UF3 LAMMPS potential file --- doc/src/pair_uf3.rst | 111 ++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 70 deletions(-) diff --git a/doc/src/pair_uf3.rst b/doc/src/pair_uf3.rst index 4c8e25d05ba..dfebf4babd8 100644 --- a/doc/src/pair_uf3.rst +++ b/doc/src/pair_uf3.rst @@ -25,24 +25,13 @@ Examples .. code-block:: LAMMPS pair_style uf3 3 - pair_coeff 1 1 Nb_Nb.uf3 - pair_coeff 3b 1 1 1 Nb_Nb_Nb.uf3 + pair_coeff * * Nb.uf3 Nb pair_style uf3 2 - pair_coeff 1 1 Nb_Nb.uf3 - pair_coeff 1 2 Nb_Sn.uf3 - pair_coeff 2 2 Sn_Sn.uf3 + pair_coeff * * NbSn.uf3 Nb Sn pair_style uf3 3 - pair_coeff 1 1 Nb_Nb.uf3 - pair_coeff 1 2 Nb_Sn.uf3 - pair_coeff 2 2 Sn_Sn.uf3 - pair_style 3b 1 1 1 Nb_Nb_Nb.uf3 - pair_style 3b 1 1 2 Nb_Nb_Sn.uf3 - pair_style 3b 1 2 2 Nb_Sn_Sn.uf3 - pair_style 3b 2 1 1 Sn_Nb_Nb.uf3 - pair_style 3b 2 1 2 Sn_Nb_Sn.uf3 - pair_style 3b 2 2 2 Sn_Sn_Sn.uf3 + pair_coeff * * NbSn.uf3 Nb Sn Description """"""""""" @@ -70,16 +59,13 @@ interaction parameters and :math:`N`, :math:`N_l`, :math:`N_m`, and :math:`N_n` denote the number of basis functions per spline or tensor spline dimension. -The UF3 LAMMPS potential files are provided using multiple pair_coeff -commands. A single UF3 LAMMPS potential file contains information about -one particular interaction only. +With *uf3* style only a single pair_coeff command is used to indicate the +UF3 LAMMPS potential file containing all the two- and three-body interactions +followed by N additional arguments specifying the mapping of UF3 elements to +LAMMPS atom types, where N is the number of LAMMPS atom types: -.. note:: - - Unlike other MANYBODY and ML potentials in LAMMPS, the atom type for - which the specified potential file should be used for is not - determined from the potential file, but is rather determined from the - user provided atom type numbers after pair_coeff. +* UF3 LAMMPS potential file +* N elements names = mapping of UF3 elements to atom types As an example, if a LAMMPS simulation contains 2 atom types (elements 'A' and 'B'), the pair_coeff command will be: @@ -87,64 +73,37 @@ As an example, if a LAMMPS simulation contains 2 atom types (elements .. code-block:: LAMMPS pair_style uf3 3 - pair_coeff 1 1 A_A.uf3 - pair_coeff 1 2 A_B.uf3 - pair_coeff 2 2 B_B.uf3 - pair_coeff 3b 1 1 1 A_A_A.uf3 - pair_coeff 3b 1 1 2 A_A_B.uf3 - pair_coeff 3b 1 2 2 A_B_B.uf3 - pair_coeff 3b 2 1 1 B_A_A.uf3 - pair_coeff 3b 2 1 2 B_A_B.uf3 - pair_coeff 3b 2 2 2 B_B_B.uf3 + pair_coeff * * AB.uf3 A B + +The AB.uf3 file should conatin all two-body (A-A, A-B, B-B) and three-body +(A-A-A, A-A-B, A-B-B, B-A-A, B-A-B, B-B-B). If a value of "2" is specified in the :code:`pair_style uf3` command, -only the two-body potential files are needed. For 3-body interaction the +only the two-body potentials are needed. For 3-body interaction the first atom type is the central atom. We recommend using the :code:`generate_uf3_lammps_pots.py` script (found `here -`_) for -generating the UF3 LAMMPS potential files from the UF3 JSON potentials. - -LAMMPS wild-card character "*" can also be used to specify a single UF3 -LAMMPS potential file for multiple interaction. For example- - -.. code-block:: LAMMPS - - pair_style uf3 3 - pair_coeff * * A_A - pair_coeff 3b 1 * * A_A_A - pair_coeff 3b 2 * * B_B_B - -The file A_A will be used for 2-body interaction between atom types 1-1, -1-2 and 2-2; file A_A_A will be used 3-body interaction for atom types -1-1-1, 1-1-2, 1-2-2; and so on. Note, using a single interaction file -for all types of interactions is **not** the recommended way of using -:code:`pair_style uf3` and will often lead to **incorrect results**. +`_) for +generating the UF3 LAMMPS potential file from the UF3 JSON potentials. ---------- -UF3 LAMMPS potential files in the *potentials* directory of the LAMMPS -distribution have a ".uf3" suffix. All UF3 LAMMPS potential files should -start with :code:`#UF3 POT` and end with :code:`#` characters. Following -shows the format of a generic 2-body UF3 LAMMPS potential file- +UF3 LAMMPS potential file in the *potentials* directory of the LAMMPS +distribution have a ".uf3" suffix. The interaction block in UF3 LAMMPS potential +file should start with :code:`#UF3 POT` and end with :code:`#` characters. +Following shows the format of a generic 2-body and 3-body potential block in +UF3 LAMMPS potential file- .. code-block:: LAMMPS #UF3 POT UNITS: units DATE: POT_GEN_DATE AUTHOR: AUTHOR_NAME CITATION: CITE - 2B LEADING_TRIM TRAILING_TRIM + 2B ELEMENT1 ELEMENT2 LEADING_TRIM TRAILING_TRIM Rij_CUTOFF NUM_OF_KNOTS BSPLINE_KNOTS NUM_OF_COEFF COEFF # - -The second line indicates whether the potential file contains data for 2-body (:code:`2B`) or 3-body (:code:`3B`) interaction. This is followed by :code:`LEADING_TRIM` and :code:`TRAILING_TRIM` number on the same line. The current implementation is only tested for :code:`LEADING_TRIM=0` and :code:`TRAILING_TRIM=3`. If other values are used LAMMPS is terminated after issuing an error message. The :code:`Rij_CUTOFF` sets the 2-body cutoff for the interaction described by the potential file. :code:`NUM_OF_KNOTS` is the number of knots (or the length of the knot vector) present on the very next line. The :code:`BSPLINE_KNOTS` line should contain all the knots in ascending order. :code:`NUM_OF_COEFF` is the number of coefficients in the :code:`COEFF` line. All the numbers in the BSPLINE_KNOTS and COEFF line should be space-separated. - -The format of a generic 3-body UF3 LAMMPS potential file is as follow- - -.. code-block:: LAMMPS - #UF3 POT UNITS: units DATE: POT_GEN_DATE AUTHOR: AUTHOR_NAME CITATION: CITE - 3B LEADING_TRIM TRAILING_TRIM + 3B ELEMENT1 ELEMENT2 ELEMENT3 LEADING_TRIM TRAILING_TRIM Rjk_CUTOFF Rik_CUTOFF Rij_CUTOFF NUM_OF_KNOTS_JK NUM_OF_KNOTS_IK NUM_OF_KNOTS_IJ BSPLINE_KNOTS_FOR_JK BSPLINE_KNOTS_FOR_IK @@ -164,10 +123,22 @@ The format of a generic 3-body UF3 LAMMPS potential file is as follow- . # -Similar to the 2-body potential file, the third line sets the cutoffs -and length of the knots. The cutoff distance between atom-type I and J -is :code:`Rij_CUTOFF`, atom-type I and K is :code:`Rik_CUTOFF` and -between J and K is :code:`Rjk_CUTOFF`. +The second line indicates whether the block contains data for 2-body +(:code:`2B`) or 3-body (:code:`3B`) interaction. This is followed by element +combination interaction, :code:`LEADING_TRIM` and :code:`TRAILING_TRIM` +number on the same line. The current implementation is only tested for +:code:`LEADING_TRIM=0` and :code:`TRAILING_TRIM=3`. +If other values are used LAMMPS is terminated after issuing an error message. +The :code:`Rij_CUTOFF` sets the 2-body cutoff for the interaction described +by the potential block. :code:`NUM_OF_KNOTS` is the number of knots +(or the length of the knot vector) present on the very next line. The +:code:`BSPLINE_KNOTS` line should contain all the knots in ascending order. +:code:`NUM_OF_COEFF` is the number of coefficients in the :code:`COEFF` line. +All the numbers in the BSPLINE_KNOTS and COEFF line should be space-separated. +Similar to the 2-body potential block, the third line sets the cutoffs and +length of the knots. The cutoff distance between atom-type I and J is +:code:`Rij_CUTOFF`, atom-type I and K is :code:`Rik_CUTOFF` and between +J and K is :code:`Rjk_CUTOFF`. .. note:: @@ -204,7 +175,7 @@ This pair style does not support the :doc:`pair_modify ` shift, table, and tail options. This pair style does not write its information to :doc:`binary restart -files `, since it is stored in potential files. +files `, since it is stored in potential file. This pair style can only be used via the *pair* keyword of the :doc:`run_style respa ` command. It does not support the @@ -219,7 +190,7 @@ if LAMMPS was built with that package. See the :doc:`Build package This pair style requires the :doc:`newton ` setting to be "on". -The UF3 LAMMPS potential files provided with LAMMPS (see the potentials +The UF3 LAMMPS potential file provided with LAMMPS (see the potentials directory) are parameterized for metal :doc:`units `. The single() function of 'uf3' pair style only return the 2-body