1 /* ----------------------------------------------------------------------
2    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
3    https://www.lammps.org/, Sandia National Laboratories
4    Steve Plimpton, sjplimp@sandia.gov
5 
6    Copyright (2003) Sandia Corporation.  Under the terms of Contract
7    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
8    certain rights in this software.  This software is distributed under
9    the GNU General Public License.
10 
11    See the README file in the top-level LAMMPS directory.
12 ------------------------------------------------------------------------- */
13 
14 /* ----------------------------------------------------------------------
15    Contributing author: Aidan Thompson (SNL)
16 ------------------------------------------------------------------------- */
17 
18 #include "mliap_model.h"
19 
20 #include "comm.h"
21 #include "error.h"
22 #include "memory.h"
23 #include "tokenizer.h"
24 
25 #include <cstring>
26 
27 using namespace LAMMPS_NS;
28 
29 #define MAXLINE 1024
30 #define MAXWORD 3
31 
32 /* ---------------------------------------------------------------------- */
33 
MLIAPModel(LAMMPS * lmp,char *)34 MLIAPModel::MLIAPModel(LAMMPS *lmp, char *) : Pointers(lmp), coeffelem(nullptr)
35 {
36   nparams = 0;
37   nelements = 0;
38   ndescriptors = 0;
39   nonlinearflag = 0;
40 }
41 
42 /* ---------------------------------------------------------------------- */
43 
~MLIAPModel()44 MLIAPModel::~MLIAPModel()
45 {
46   memory->destroy(coeffelem);
47 }
48 
49 /* ----------------------------------------------------------------------
50    placeholder
51 ------------------------------------------------------------------------- */
52 
init()53 void MLIAPModel::init() {}
54 
55 /* ----------------------------------------------------------------------
56    set number of elements
57    ---------------------------------------------------------------------- */
58 
set_nelements(int nelements_in)59 void MLIAPModel::set_nelements(int nelements_in)
60 {
61   nelements = nelements_in;
62 }
63 
64 /* ----------------------------------------------------------------------
65    set number of descriptors
66    ---------------------------------------------------------------------- */
67 
set_ndescriptors(int ndescriptors_in)68 void MLIAPModel::set_ndescriptors(int ndescriptors_in)
69 {
70   ndescriptors = ndescriptors_in;
71 }
72 
73 /* ---------------------------------------------------------------------- */
74 
MLIAPModelSimple(LAMMPS * lmp,char * coefffilename)75 MLIAPModelSimple::MLIAPModelSimple(LAMMPS *lmp, char *coefffilename) :
76     MLIAPModel(lmp, coefffilename)
77 {
78   if (coefffilename) MLIAPModelSimple::read_coeffs(coefffilename);
79 }
80 
81 /* ---------------------------------------------------------------------- */
82 
read_coeffs(char * coefffilename)83 void MLIAPModelSimple::read_coeffs(char *coefffilename)
84 {
85 
86   // open coefficient file on proc 0
87 
88   FILE *fpcoeff;
89   if (comm->me == 0) {
90     fpcoeff = utils::open_potential(coefffilename, lmp, nullptr);
91     if (fpcoeff == nullptr)
92       error->one(FLERR, "Cannot open MLIAPModel coeff file {}: {}", coefffilename,
93                  utils::getsyserror());
94   }
95 
96   char line[MAXLINE], *ptr;
97   int eof = 0;
98 
99   int n;
100   int nwords = 0;
101   while (nwords == 0) {
102     if (comm->me == 0) {
103       ptr = fgets(line, MAXLINE, fpcoeff);
104       if (ptr == nullptr) {
105         eof = 1;
106         fclose(fpcoeff);
107       } else
108         n = strlen(line) + 1;
109     }
110     MPI_Bcast(&eof, 1, MPI_INT, 0, world);
111     if (eof) break;
112     MPI_Bcast(&n, 1, MPI_INT, 0, world);
113     MPI_Bcast(line, n, MPI_CHAR, 0, world);
114 
115     // strip comment, skip line if blank
116 
117     if ((ptr = strchr(line, '#'))) *ptr = '\0';
118     nwords = utils::count_words(line);
119   }
120   if (nwords != 2) error->all(FLERR, "Incorrect format in MLIAPModel coefficient file");
121 
122   // words = ptrs to all words in line
123   // strip single and double quotes from words
124 
125   try {
126     ValueTokenizer coeffs(line);
127     nelements = coeffs.next_int();
128     nparams = coeffs.next_int();
129   } catch (TokenizerException &e) {
130     error->all(FLERR,
131                "Incorrect format in MLIAPModel coefficient "
132                "file: {}",
133                e.what());
134   }
135 
136   // set up coeff lists
137 
138   memory->destroy(coeffelem);
139   memory->create(coeffelem, nelements, nparams, "mliap_snap_model:coeffelem");
140 
141   // Loop over nelements blocks in the coefficient file
142 
143   for (int ielem = 0; ielem < nelements; ielem++) {
144     for (int icoeff = 0; icoeff < nparams; icoeff++) {
145       if (comm->me == 0) {
146         ptr = fgets(line, MAXLINE, fpcoeff);
147         if (ptr == nullptr) {
148           eof = 1;
149           fclose(fpcoeff);
150         } else
151           n = strlen(line) + 1;
152       }
153 
154       MPI_Bcast(&eof, 1, MPI_INT, 0, world);
155       if (eof) error->all(FLERR, "Incorrect format in MLIAPModel coefficient file");
156       MPI_Bcast(&n, 1, MPI_INT, 0, world);
157       MPI_Bcast(line, n, MPI_CHAR, 0, world);
158 
159       try {
160         ValueTokenizer coeffs(utils::trim_comment(line));
161         if (coeffs.count() != 1) throw TokenizerException("Wrong number of items", "");
162         coeffelem[ielem][icoeff] = coeffs.next_double();
163       } catch (TokenizerException &e) {
164         error->all(FLERR,
165                    "Incorrect format in MLIAPModel "
166                    "coefficient file: {}",
167                    e.what());
168       }
169     }
170   }
171   if (comm->me == 0) fclose(fpcoeff);
172 }
173 
174 /* ----------------------------------------------------------------------
175    memory usage
176 ------------------------------------------------------------------------- */
177 
memory_usage()178 double MLIAPModelSimple::memory_usage()
179 {
180   double bytes = 0;
181 
182   bytes += (double) nelements * nparams * sizeof(double);    // coeffelem
183   return bytes;
184 }
185