17
17
######################################################################
18
18
# Misc functions.
19
19
######################################################################
20
- def resolve_status (runner ,reader ,outfile , method = 'not_defined' ):
20
+ def resolve_status (runner ,reader ,outfile ):
21
21
#Check if the reader is done
22
22
if reader .completed :
23
23
return 'done'
@@ -67,19 +67,44 @@ def update_attributes(copyto,copyfrom,skip_keys=[],take_keys=[]):
67
67
pass
68
68
return updated
69
69
70
+ def seperate_jastrow (wffile ,optimizebasis = False ):
71
+ ''' Seperate the jastrow section of a QWalk wave function file.'''
72
+ # Copied from utils/seperate_jastrow TODO: no copy, bad
73
+ wff = open (wffile ,'r' )
74
+ tokens = wff .read ().split ('\n ' )
75
+ in_jastrow = False
76
+ nopen = 0
77
+ nclose = 0
78
+ jastlines = []
79
+ for line in tokens :
80
+ if 'jastrow2' in line .lower ():
81
+ in_jastrow = True
82
+ if in_jastrow :
83
+ if not optimizebasis and 'optimizebasis' in line .lower ():
84
+ continue
85
+ nopen += line .count ("{" )
86
+ nclose += line .count ("}" )
87
+ if in_jastrow and nopen >= nclose :
88
+ jastlines .append (line )
89
+ return '\n ' .join (jastlines )
90
+
70
91
######################################################################
71
92
# Manager classes.
72
93
#######################################################################
73
94
class CrystalManager :
74
95
""" Internal class managing process of running a DFT job though crystal.
75
96
Has authority over file names associated with this task."""
76
- def __init__ (self ,writer ,runner ,name = 'crystal_run' ,path = None ,crys_reader = None ,prop_reader = None ,
97
+ def __init__ (self ,writer ,runner ,creader = None ,name = 'crystal_run' ,path = None ,
98
+ preader = None ,prunner = None ,
77
99
trylev = False ,bundle = False ,max_restarts = 5 ):
78
100
''' CrystalManager manages the writing of a Crystal input file, it's running, and keeping track of the results.
79
101
Args:
80
102
writer (PySCFWriter): writer for input.
81
103
reader (PySCFReader): to read PySCF output.
82
104
runner (runner object): to run job.
105
+ creader (CrystalReader): Reads the crystal results, (None implies use default reader).
106
+ preader (PropertiesReader): Reads properties results, if any (None implies use default reader).
107
+ prunner (runner object): run properties if needed (None implies use same runner as crystal).
83
108
name (str): identifier for this job. This names the files associated with run.
84
109
trylev (bool): When restarting use LEVSHIFT option to encourage convergence, then do a rerun without LEVSHIFT.
85
110
bundle (bool): Whether you'll use a bundling tool to run these jobs.
@@ -99,11 +124,14 @@ def __init__(self,writer,runner,name='crystal_run',path=None,crys_reader=None,pr
99
124
100
125
print (self .logname ,": initializing" )
101
126
127
+ # Handle reader and runner defaults.
102
128
self .writer = writer
103
- if crys_reader is None : self .creader = crystal .CrystalReader ()
104
- else : self .creader = crys_reader
105
- if prop_reader is None : self .preader = propertiesreader .PropertiesReader ()
106
- else : self .preader = prop_reader
129
+ if creader is None : self .creader = crystal .CrystalReader ()
130
+ else : self .creader = creader
131
+ if preader is None : self .preader = propertiesreader .PropertiesReader ()
132
+ else : self .preader = preader
133
+ if prunner is None : self .prunner = runner
134
+ else : self .prunner = prunner
107
135
if runner is None : self .runner = RunnerPBS ()
108
136
else : self .runner = runner
109
137
@@ -143,15 +171,18 @@ def recover(self,other):
143
171
# This is because you are taking the attributes from the older instance, and copying into the new instance.
144
172
145
173
update_attributes (copyto = self ,copyfrom = other ,
146
- skip_keys = ['writer' ,'runner' ,'creader' ,'preader' ,'lev' ,'savebroy' ,
174
+ skip_keys = ['writer' ,'runner' ,'creader' ,'preader' ,'prunner' , ' lev' ,'savebroy' ,
147
175
'path' ,'logname' ,'name' ,
148
176
'trylev' ,'max_restarts' ,'bundle' ],
149
- take_keys = ['restarts' ,'completed' ])
177
+ take_keys = ['restarts' ,'completed' , 'qwfiles' ])
150
178
151
179
# Update queue settings, but save queue information.
152
180
update_attributes (copyto = self .runner ,copyfrom = other .runner ,
153
181
skip_keys = ['queue' ,'walltime' ,'np' ,'nn' ,'jobname' ],
154
182
take_keys = ['queueid' ])
183
+ update_attributes (copyto = self .runner ,copyfrom = other .runner ,
184
+ skip_keys = ['queue' ,'walltime' ,'np' ,'nn' ,'jobname' ],
185
+ take_keys = ['queueid' ])
155
186
156
187
update_attributes (copyto = self .creader ,copyfrom = other .creader ,
157
188
skip_keys = [],
@@ -185,7 +216,7 @@ def nextstep(self):
185
216
self .writer .write_prop_input (self .propinpfn )
186
217
187
218
# Check on the CRYSTAL run
188
- status = resolve_status (self .runner ,self .creader ,self .crysoutfn , method = 'crystal' )
219
+ status = resolve_status (self .runner ,self .creader ,self .crysoutfn )
189
220
print (self .logname ,": status= %s" % (status ))
190
221
191
222
if status == "not_started" :
@@ -237,7 +268,7 @@ def nextstep(self):
237
268
# Ready for bundler or else just submit the jobs as needed.
238
269
if self .bundle :
239
270
self .scriptfile = "%s.run" % self .name
240
- self .bundle_ready = self .runner .script (self .scriptfile , self . driverfn )
271
+ self .bundle_ready = self .runner .script (self .scriptfile )
241
272
else :
242
273
qsubfile = self .runner .submit ()
243
274
@@ -284,16 +315,38 @@ def export_qwalk(self):
284
315
''' Export QWalk input files into current directory.'''
285
316
if len (self .qwfiles )== 0 :
286
317
self .nextstep ()
318
+
287
319
if not self .completed :
288
320
return False
289
- else :
290
- print (self .logname ,": %s generating QWalk files." % self .name )
291
- cwd = os .getcwd ()
292
- os .chdir (self .path )
293
- self .qwfiles = crystal2qmc .convert_crystal (base = self .name )
294
- os .chdir (cwd )
321
+
322
+ cwd = os .getcwd ()
323
+ os .chdir (self .path )
324
+
325
+ print (self .logname ,": %s attempting to generate QWalk files." % self .name )
326
+
327
+ # Check on the properties run
328
+ status = resolve_status (self .prunner ,self .preader ,self .propoutfn )
329
+ print (self .logname ,": properties status= %s" % (status ))
330
+ if status == 'not_started' :
331
+ self .prunner .add_command ("cp %s INPUT" % self .propinpfn )
332
+ self .prunner .add_task ("Pproperties &> %s" % self .propoutfn )
333
+
334
+ if self .bundle :
335
+ self .scriptfile = "%s.run" % self .name
336
+ self .bundle_ready = self .prunner .script (self .scriptfile ,self .driverfn )
337
+ else :
338
+ qsubfile = self .runner .submit ()
339
+ elif status == 'ready_for_analysis' :
340
+ self .preader .collect (self .propoutfn )
341
+
342
+ if self .preader .completed :
343
+ self .qwfiles = crystal2qmc .convert_crystal (base = self .name ,propoutfn = self .propoutfn )
344
+ print (self .logname ,": crystal converted to QWalk input." )
345
+
346
+ os .chdir (cwd )
295
347
with open (self .path + self .pickle ,'wb' ) as outf :
296
348
pkl .dump (self ,outf )
349
+
297
350
return True
298
351
299
352
#----------------------------------------
@@ -381,7 +434,7 @@ def nextstep(self):
381
434
if not self .writer .completed :
382
435
self .writer .pyscf_input (self .driverfn ,self .chkfile )
383
436
384
- status = resolve_status (self .runner ,self .reader ,self .outfile , 'pyscf' )
437
+ status = resolve_status (self .runner ,self .reader ,self .outfile )
385
438
print (self .logname ,": %s status= %s" % (self .name ,status ))
386
439
387
440
if status == "not_started" :
@@ -429,20 +482,19 @@ def export_qwalk(self):
429
482
self .nextstep ()
430
483
if not self .completed :
431
484
return False
432
- else :
433
- print (self .logname ,": %s generating QWalk files." % self .name )
434
- cwd = os .getcwd ()
435
- os .chdir (self .path )
436
- self .qwfiles = pyscf2qwalk .print_qwalk_chkfile (self .chkfile )
437
- os .chdir (cwd )
485
+ print (self .logname ,": %s generating QWalk files." % self .name )
486
+ cwd = os .getcwd ()
487
+ os .chdir (self .path )
488
+ self .qwfiles = pyscf2qwalk .print_qwalk_chkfile (self .chkfile )
489
+ os .chdir (cwd )
438
490
with open (self .path + self .pickle ,'wb' ) as outf :
439
491
pkl .dump (self ,outf )
440
492
return True
441
493
442
494
#----------------------------------------
443
495
def status (self ):
444
496
''' Determine the course of action based on info from reader and runner.'''
445
- current_status = resolve_status (self .runner ,self .reader ,self .outfile , 'pyscf' )
497
+ current_status = resolve_status (self .runner ,self .reader ,self .outfile )
446
498
if current_status == 'done' :
447
499
return 'ok'
448
500
elif current_status == 'retry' :
@@ -492,6 +544,7 @@ def __init__(self,writer,reader,runner=None,trialfunc=None,
492
544
self .bundle_ready = False
493
545
self .infile = "%s.%s" % (name ,writer .qmc_abr )
494
546
self .outfile = "%s.o" % self .infile
547
+ self .qwfiles = {}
495
548
self .stdout = "%s.out" % self .infile
496
549
497
550
# Handle old results if present.
@@ -584,7 +637,7 @@ def nextstep(self):
584
637
self .completed = True
585
638
else :
586
639
print (self .logname ,": %s status= %s, attempting rerun." % (self .name ,status ))
587
- exestr = "%s %s" % ' ' .join (self .qwalk ,self .infile )
640
+ exestr = "%s %s" % ' ' .join (( self .qwalk ,self .infile ) )
588
641
exestr += " &> %s.out" % self .infile [- 1 ]
589
642
self .runner .add_task (exestr )
590
643
elif status == 'done' :
@@ -595,7 +648,7 @@ def nextstep(self):
595
648
# Ready for bundler or else just submit the jobs as needed.
596
649
if self .bundle :
597
650
self .scriptfile = "%s.run" % self .name
598
- self .bundle_ready = self .runner .script (self .scriptfile , self . driverfn )
651
+ self .bundle_ready = self .runner .script (self .scriptfile )
599
652
else :
600
653
qsubfile = self .runner .submit ()
601
654
@@ -639,3 +692,27 @@ def collect(self):
639
692
with open (self .path + self .pickle ,'wb' ) as outf :
640
693
pkl .dump (self ,outf )
641
694
695
+ #----------------------------------------
696
+ def export_qwalk (self ):
697
+ ''' Extract jastrow from the optimization run and return that file name.'''
698
+ # Theoretically more than just Jastrow can be provided, but practically that's the only type of wavefunction we tend to export.
699
+
700
+ assert self .writer .qmc_abr != 'dmc' ,"DMC doesn't provide a wave function."
701
+
702
+ if len (self .qwfiles )== 0 :
703
+ self .nextstep ()
704
+ if not self .completed :
705
+ return False
706
+ print (self .logname ,": %s generating QWalk files." % self .name )
707
+ cwd = os .getcwd ()
708
+ os .chdir (self .path )
709
+ self .qwfiles ['wfout' ]= "%s.wfout" % self .infile
710
+ newjast = seperate_jastrow (self .qwfiles ['wfout' ])
711
+ self .qwfiles ['jastrow2' ]= "%s.jast" % self .infile
712
+ with open (self .qwfiles ['jastrow2' ],'w' ) as outf :
713
+ outf .write (newjast )
714
+ os .chdir (cwd )
715
+
716
+ with open (self .path + self .pickle ,'wb' ) as outf :
717
+ pkl .dump (self ,outf )
718
+ return True
0 commit comments