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