Skip to content

Commit a8578b7

Browse files
authored
Merge pull request #105 from amcadmus/devel
Implement dipole
2 parents bc8adbe + 080a708 commit a8578b7

File tree

13 files changed

+350
-175
lines changed

13 files changed

+350
-175
lines changed

deepmd/__init__.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from .env import set_mkl
2-
from .DeepEval import DeepEval
3-
from .DeepPot import DeepPot
4-
from .DeepPolar import DeepPolar
5-
from .DeepWFC import DeepWFC
2+
from .DeepEval import DeepEval
3+
from .DeepPot import DeepPot
4+
from .DeepDipole import DeepDipole
5+
from .DeepPolar import DeepPolar
6+
from .DeepWFC import DeepWFC
67

78
set_mkl()
89

examples/water/train/polar.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"_comment": " model parameters",
44
"model":{
55
"type_map": ["O", "H"],
6+
"data_stat_nbatch": 1,
67
"descriptor": {
78
"type": "loc_frame",
89
"sel_a": [16, 32],

examples/water/train/polar_se_a.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"_comment": " model parameters",
44
"model":{
55
"type_map": ["O", "H"],
6+
"data_stat_nbatch": 1,
67
"descriptor" :{
78
"type": "se_a",
89
"sel": [46, 92],

examples/water/train/wannier.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"_comment": " model parameters",
44
"model":{
55
"type_map": ["O", "H"],
6+
"data_stat_nbatch": 1,
67
"descriptor": {
78
"type": "loc_frame",
89
"sel_a": [16, 32],

source/scripts/freeze.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ def _make_node_names(model_type = None) :
4040
nodes = "o_energy,o_force,o_virial,o_atom_energy,o_atom_virial,descrpt_attr/rcut,descrpt_attr/ntypes,fitting_attr/dfparam,fitting_attr/daparam,model_attr/tmap,model_attr/model_type"
4141
elif model_type == 'wfc':
4242
nodes = "o_wfc,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type"
43+
elif model_type == 'dipole':
44+
nodes = "o_dipole,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type"
4345
elif model_type == 'polar':
4446
nodes = "o_polar,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type"
4547
else:

source/tests/test_wfc.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import dpdata,os,sys,json,unittest
2+
import numpy as np
3+
from deepmd.env import tf
4+
from common import Data,gen_data
5+
6+
from deepmd.RunOptions import RunOptions
7+
from deepmd.DataSystem import DataSystem
8+
from deepmd.DescrptLocFrame import DescrptLocFrame
9+
from deepmd.Fitting import WFCFitting
10+
from deepmd.Model import WFCModel
11+
from deepmd.common import j_must_have, j_must_have_d, j_have
12+
13+
global_ener_float_precision = tf.float64
14+
global_tf_float_precision = tf.float64
15+
global_np_float_precision = np.float64
16+
17+
class TestModel(unittest.TestCase):
18+
def setUp(self) :
19+
gen_data()
20+
21+
def test_model(self):
22+
jfile = 'wfc.json'
23+
with open(jfile) as fp:
24+
jdata = json.load (fp)
25+
run_opt = RunOptions(None)
26+
systems = j_must_have(jdata, 'systems')
27+
set_pfx = j_must_have(jdata, 'set_prefix')
28+
batch_size = j_must_have(jdata, 'batch_size')
29+
test_size = j_must_have(jdata, 'numb_test')
30+
batch_size = 1
31+
test_size = 1
32+
stop_batch = j_must_have(jdata, 'stop_batch')
33+
rcut = j_must_have (jdata['model']['descriptor'], 'rcut')
34+
35+
data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt = None)
36+
37+
test_data = data.get_test ()
38+
numb_test = 1
39+
40+
descrpt = DescrptLocFrame(jdata['model']['descriptor'])
41+
fitting = WFCFitting(jdata['model']['fitting_net'], descrpt)
42+
model = WFCModel(jdata['model'], descrpt, fitting)
43+
44+
input_data = {'coord' : [test_data['coord']],
45+
'box': [test_data['box']],
46+
'type': [test_data['type']],
47+
'natoms_vec' : [test_data['natoms_vec']],
48+
'default_mesh' : [test_data['default_mesh']],
49+
'fparam': [test_data['fparam']],
50+
}
51+
model._compute_dstats(input_data)
52+
53+
t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c')
54+
t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy')
55+
t_force = tf.placeholder(global_tf_float_precision, [None], name='t_force')
56+
t_virial = tf.placeholder(global_tf_float_precision, [None], name='t_virial')
57+
t_atom_ener = tf.placeholder(global_tf_float_precision, [None], name='t_atom_ener')
58+
t_coord = tf.placeholder(global_tf_float_precision, [None], name='i_coord')
59+
t_type = tf.placeholder(tf.int32, [None], name='i_type')
60+
t_natoms = tf.placeholder(tf.int32, [model.ntypes+2], name='i_natoms')
61+
t_box = tf.placeholder(global_tf_float_precision, [None, 9], name='i_box')
62+
t_mesh = tf.placeholder(tf.int32, [None], name='i_mesh')
63+
is_training = tf.placeholder(tf.bool)
64+
t_fparam = None
65+
66+
model_pred \
67+
= model.build (t_coord,
68+
t_type,
69+
t_natoms,
70+
t_box,
71+
t_mesh,
72+
t_fparam,
73+
suffix = "wfc",
74+
reuse = False)
75+
wfc = model_pred['wfc']
76+
77+
feed_dict_test = {t_prop_c: test_data['prop_c'],
78+
t_coord: np.reshape(test_data['coord'] [:numb_test, :], [-1]),
79+
t_box: test_data['box'] [:numb_test, :],
80+
t_type: np.reshape(test_data['type'] [:numb_test, :], [-1]),
81+
t_natoms: test_data['natoms_vec'],
82+
t_mesh: test_data['default_mesh'],
83+
is_training: False}
84+
85+
sess = tf.Session()
86+
sess.run(tf.global_variables_initializer())
87+
[p] = sess.run([wfc], feed_dict = feed_dict_test)
88+
89+
p = p.reshape([-1])
90+
refp = [-9.105016838228578990e-01,7.196284362034099935e-01,-9.548516928185298014e-02,2.764615027095288724e+00,2.661319598995644520e-01,7.579512949131941846e-02,-2.107409067376114997e+00,-1.299080016614967414e-01,-5.962778584850070285e-01,2.913899917663253514e-01,-1.226917174638697094e+00,1.829523069930876655e+00,1.015704024959750873e+00,-1.792333611099589386e-01,5.032898080485321834e-01,1.808561721292949453e-01,2.468863482075112081e+00,-2.566442546384765100e-01,-1.467453783795173994e-01,-1.822963931552128658e+00,5.843600156865462747e-01,-1.493875280832117403e+00,1.693322352814763398e-01,-1.877325443995481624e+00]
91+
92+
places = 6
93+
for ii in range(p.size) :
94+
self.assertAlmostEqual(p[ii], refp[ii], places = places)
95+
96+
97+

source/tests/wfc.json

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"with_distrib": false,
3+
"_comment": " model parameters",
4+
"model":{
5+
"type": "polar",
6+
"type_map": ["O", "H"],
7+
"descriptor" :{
8+
"type": "loc_frame",
9+
"sel_a": [16, 32],
10+
"sel_r": [30, 60],
11+
"rcut": 6.00,
12+
"axis_rule": [0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0],
13+
"_comment": " default rule: []",
14+
"_comment": " user defined rule: for each type provides two axes, ",
15+
"_comment": " for each axis: (a_or_r, type, idx)",
16+
"_comment": " if type < 0, exclude type -(type+1)",
17+
"_comment": " for water (O:0, H:1) it can be",
18+
"_comment": " [0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0]",
19+
"_comment": " that's all"
20+
},
21+
"fitting_net": {
22+
"type": "wfc",
23+
"wfc_numb": 4,
24+
"sel_type": [0],
25+
"neuron": [100, 100, 100],
26+
"resnet_dt": true,
27+
"seed": 1,
28+
"_comment": " that's all"
29+
},
30+
"_comment": " that's all"
31+
},
32+
33+
"learning_rate" :{
34+
"type": "exp",
35+
"start_lr": 0.001,
36+
"decay_steps": 5000,
37+
"decay_rate": 0.95,
38+
"_comment": "that's all"
39+
},
40+
41+
"_comment": " traing controls",
42+
"systems": ["system"],
43+
"set_prefix": "set",
44+
"stop_batch": 1000000,
45+
"batch_size": [1],
46+
47+
"seed": 1,
48+
49+
"_comment": " display and restart",
50+
"_comment": " frequencies counted in batch",
51+
"disp_file": "lcurve.out",
52+
"disp_freq": 100,
53+
"numb_test": 10,
54+
"save_freq": 1000,
55+
"save_ckpt": "model.ckpt",
56+
"load_ckpt": "model.ckpt",
57+
"disp_training":true,
58+
"time_training":true,
59+
60+
"_comment": "that's all"
61+
}
62+

source/train/DeepDipole.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env python3
2+
3+
import os,sys
4+
import numpy as np
5+
from deepmd.DeepEval import DeepTensor
6+
7+
class DeepDipole (DeepTensor) :
8+
def __init__(self,
9+
model_file) :
10+
DeepTensor.__init__(self, model_file, 'dipole', 3)
11+

source/train/Fitting.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ def get_sel_type(self):
211211
def get_wfc_numb(self):
212212
return self.wfc_numb
213213

214+
def get_out_size(self):
215+
return self.wfc_numb * 3
216+
214217
def build (self,
215218
input_d,
216219
rot_mat,
@@ -283,6 +286,9 @@ def __init__ (self, jdata, descrpt) :
283286
def get_sel_type(self):
284287
return self.sel_type
285288

289+
def get_out_size(self):
290+
return 9
291+
286292
def build (self,
287293
input_d,
288294
rot_mat,
@@ -360,6 +366,9 @@ def __init__ (self, jdata, descrpt) :
360366
def get_sel_type(self):
361367
return self.sel_type
362368

369+
def get_out_size(self):
370+
return 9
371+
363372
def build (self,
364373
input_d,
365374
rot_mat,
@@ -412,3 +421,76 @@ def build (self,
412421
count += 1
413422

414423
return tf.reshape(outs, [-1])
424+
425+
426+
class DipoleFittingSeA () :
427+
def __init__ (self, jdata, descrpt) :
428+
if not isinstance(descrpt, DescrptSeA) :
429+
raise RuntimeError('DipoleFittingSeA only supports DescrptSeA')
430+
self.ntypes = descrpt.get_ntypes()
431+
self.dim_descrpt = descrpt.get_dim_out()
432+
args = ClassArg()\
433+
.add('neuron', list, default = [120,120,120], alias = 'n_neuron')\
434+
.add('resnet_dt', bool, default = True)\
435+
.add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'dipole_type')\
436+
.add('seed', int)
437+
class_data = args.parse(jdata)
438+
self.n_neuron = class_data['neuron']
439+
self.resnet_dt = class_data['resnet_dt']
440+
self.sel_type = class_data['sel_type']
441+
self.seed = class_data['seed']
442+
self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1()
443+
self.dim_rot_mat = self.dim_rot_mat_1 * 3
444+
self.useBN = False
445+
446+
def get_sel_type(self):
447+
return self.sel_type
448+
449+
def build (self,
450+
input_d,
451+
rot_mat,
452+
natoms,
453+
reuse = None,
454+
suffix = '') :
455+
start_index = 0
456+
inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]])
457+
rot_mat = tf.reshape(rot_mat, [-1, self.dim_rot_mat * natoms[0]])
458+
shape = inputs.get_shape().as_list()
459+
460+
count = 0
461+
for type_i in range(self.ntypes):
462+
# cut-out inputs
463+
inputs_i = tf.slice (inputs,
464+
[ 0, start_index* self.dim_descrpt],
465+
[-1, natoms[2+type_i]* self.dim_descrpt] )
466+
inputs_i = tf.reshape(inputs_i, [-1, self.dim_descrpt])
467+
rot_mat_i = tf.slice (rot_mat,
468+
[ 0, start_index* self.dim_rot_mat],
469+
[-1, natoms[2+type_i]* self.dim_rot_mat] )
470+
rot_mat_i = tf.reshape(rot_mat_i, [-1, self.dim_rot_mat_1, 3])
471+
start_index += natoms[2+type_i]
472+
if not type_i in self.sel_type :
473+
continue
474+
layer = inputs_i
475+
for ii in range(0,len(self.n_neuron)) :
476+
if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] :
477+
layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt)
478+
else :
479+
layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed)
480+
# (nframes x natoms) x naxis
481+
final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed)
482+
# (nframes x natoms) x 1 * naxis
483+
final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], 1, self.dim_rot_mat_1])
484+
# (nframes x natoms) x 1 x 3(coord)
485+
final_layer = tf.matmul(final_layer, rot_mat_i)
486+
# nframes x natoms x 3
487+
final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i], 3])
488+
489+
# concat the results
490+
if count == 0:
491+
outs = final_layer
492+
else:
493+
outs = tf.concat([outs, final_layer], axis = 1)
494+
count += 1
495+
496+
return tf.reshape(outs, [-1])

source/train/Loss.py

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -166,57 +166,8 @@ def print_on_training(self,
166166
if self.has_pf:
167167
print_str += prop_fmt % (np.sqrt(error_pf_test) / natoms[0], np.sqrt(error_pf_train) / natoms[0])
168168

169-
return print_str
170-
171-
172-
173-
class WFCLoss () :
174-
def __init__ (self, jdata, **kwarg) :
175-
model = kwarg['model']
176-
# data required
177-
add_data_requirement('wfc',
178-
model.get_wfc_numb() * 3,
179-
atomic=True,
180-
must=True,
181-
high_prec=False,
182-
type_sel = model.get_sel_type())
183-
184-
def build (self,
185-
learning_rate,
186-
natoms,
187-
model_dict,
188-
label_dict,
189-
suffix):
190-
wfc_hat = label_dict['wfc']
191-
wfc = model_dict['wfc']
192-
l2_loss = tf.reduce_mean( tf.square(wfc - wfc_hat), name='l2_'+suffix)
193-
self.l2_l = l2_loss
194-
more_loss = {}
195-
196-
return l2_loss, more_loss
197-
198-
def print_header(self) :
199-
prop_fmt = ' %9s %9s'
200-
print_str = ''
201-
print_str += prop_fmt % ('l2_tst', 'l2_trn')
202-
return print_str
203-
204-
def print_on_training(self,
205-
sess,
206-
natoms,
207-
feed_dict_test,
208-
feed_dict_batch) :
209-
error_test\
210-
= sess.run([self.l2_l], \
211-
feed_dict=feed_dict_test)
212-
error_train\
213-
= sess.run([self.l2_l], \
214-
feed_dict=feed_dict_batch)
215-
print_str = ""
216-
prop_fmt = " %9.2e %9.2e"
217-
print_str += prop_fmt % (np.sqrt(error_test), np.sqrt(error_train))
169+
return print_str
218170

219-
return print_str
220171

221172

222173
class TensorLoss () :
@@ -235,7 +186,7 @@ def __init__ (self, jdata, **kwarg) :
235186
atomic=True,
236187
must=True,
237188
high_prec=False,
238-
type_sel = model.get_sel_type())
189+
type_sel = type_sel)
239190

240191
def build (self,
241192
learning_rate,

0 commit comments

Comments
 (0)