88import math
99import os
1010from typing import TYPE_CHECKING , List , Optional , Tuple , Union
11- import socket
1211
1312from mako .template import Template
1413
1514from arc .common import get_logger
16- from arc .exceptions import JobError
1715from arc .imports import incore_commands , settings
1816from arc .job .adapter import JobAdapter
1917from arc .job .adapters .common import (_initialize_adapter ,
3735 settings ['output_filenames' ], settings ['servers' ], settings ['submit_filenames' ]
3836
3937input_template = """***,${label}
40- memory,${memory},m;
38+ memory,Total= ${memory},m;
4139
4240geometry={angstrom;
4341${xyz}}
4745${auxiliary_basis}
4846${cabs}
4947int;
48+
5049{hf;${shift}
51- maxit,1000;
52- wf,spin=${spin},charge=${charge};}
50+ maxit,999;
51+ wf,spin=${spin},charge=${charge};
52+ }
5353
54- ${restricted}${method};
54+ ${restricted}${method}
5555
5656${job_type_1}
5757${job_type_2}${block}
@@ -213,7 +213,6 @@ def write_input_file(self) -> None:
213213 'keywords' ,
214214 'memory' ,
215215 'method' ,
216- 'orbitals' ,
217216 'restricted' ,
218217 ]:
219218 input_dict [key ] = ''
@@ -224,10 +223,11 @@ def write_input_file(self) -> None:
224223 input_dict ['charge' ] = self .charge
225224 input_dict ['label' ] = self .species_label
226225 input_dict ['memory' ] = self .input_file_memory
227- input_dict ['method' ] = self .level .method
226+ input_dict ['method' ] = f' { self .level .method } ;'
228227 input_dict ['shift' ] = self .args ['trsh' ]['shift' ] if 'shift' in self .args ['trsh' ].keys () else ''
229228 input_dict ['spin' ] = self .multiplicity - 1
230229 input_dict ['xyz' ] = xyz_to_str (self .xyz )
230+ input_dict ['orbitals' ] = '\n gprint,orbitals;\n '
231231
232232 if not is_restricted (self ):
233233 input_dict ['restricted' ] = 'u'
@@ -249,23 +249,44 @@ def write_input_file(self) -> None:
249249 pass
250250
251251 if 'IGNORE_ERROR in the ORBITAL directive' in self .args ['trsh' ].keys ():
252- keywords .append ('ORBITAL,IGNORE_ERROR' )
253-
254- if 'mrci' in self .level .method :
255- if self .species [0 ].occ > 16 :
256- raise JobError (f'Will not execute an MRCI calculation with more than 16 occupied orbitals '
257- f'(got { self .species [0 ].occ } ).\n '
258- f'Selective occ, closed, core, frozen keyword still not implemented.' )
259- input_dict ['orbitals' ] = '\n gprint,orbitals;\n '
260- input_dict ['block' ] += '\n \n E_mrci=energy;\n E_mrci_Davidson=energd;\n \n table,E_mrci,E_mrci_Davidson;'
261- input_dict ['method' ] = input_dict ['rerstricted' ] = ''
262- input_dict ['shift' ] = 'shift,-1.0,-0.5;'
263- input_dict ['job_type_1' ] = f"""{{multi;
264- { self .species [0 ].occ } noextra,failsafe,config,csf;
265- wf,spin={ input_dict ['spin' ]} ,charge={ input_dict ['charge' ]} ;
266- natorb,print,ci;}}"""
267- input_dict ['job_type_2' ] = f"""{{mrci;
268- ${ self .species [0 ].occ } wf,spin=${ input_dict ['spin' ]} ,charge=${ input_dict ['charge' ]} ;}}"""
252+ keywords .append (' ORBITAL,IGNORE_ERROR;' )
253+
254+ if 'mrci' in self .level .method or 'rs2' in self .level .method :
255+ active = self .species [0 ].active
256+ input_dict ['restricted' ] = ''
257+ if '_' in self .level .method :
258+ methods = self .level .method .split ('_' )
259+ input_dict ['method' ] = ''
260+ for method in methods :
261+ input_dict ['method' ] += '\n {' + method .lower () + ';\n '
262+ if 'mp2' not in method .lower ():
263+ input_dict ['method' ] += ' maxit,999;\n '
264+ input_dict ['method' ] += f' wf,spin={ input_dict ["spin" ]} ,charge={ input_dict ["charge" ]} ;\n '
265+ if 'casscf' in method .lower () and active is not None :
266+ if 'occ' in active :
267+ input_dict ['method' ] += f' occ,{ "," .join ([str (i ) for i in active ["occ" ]])} ;\n '
268+ if 'closed' in active :
269+ input_dict ['method' ] += f' closed,{ "," .join ([str (i ) for i in active ["closed" ]])} ;\n '
270+ input_dict ['method' ] += ' state,1;\n ' # ground state
271+ input_dict ['method' ] += '}\n '
272+ else :
273+ input_dict ['method' ] = f"""{{casscf;
274+ maxit,999;
275+ wf,spin={ input_dict ['spin' ]} ,charge={ input_dict ['charge' ]} ;
276+ """
277+ if active is not None :
278+ if 'occ' in active :
279+ input_dict ['method' ] += f' occ,{ "," .join ([str (i ) for i in active ["occ" ]])} ;\n '
280+ if 'closed' in active :
281+ input_dict ['method' ] += f' closed,{ "," .join ([str (i ) for i in active ["closed" ]])} ;\n '
282+ input_dict ['method' ] += ' state,1;\n ' # ground state
283+ input_dict ['method' ] += '}\n \n '
284+ input_dict ['method' ] += f"""{{mrci{ "-f12" if "f12" in self .level .method .lower () else "" } ;
285+ maxit,999;
286+ wf,spin={ input_dict ['spin' ]} ,charge={ input_dict ['charge' ]} ;
287+ }}"""
288+ if 'mrci' in self .level .method :
289+ input_dict ['block' ] += '\n \n E_mrci=energy;\n E_mrci_Davidson=energd;\n \n table,E_mrci,E_mrci_Davidson;'
269290
270291 input_dict = update_input_dict_with_args (args = self .args , input_dict = input_dict )
271292
@@ -325,19 +346,12 @@ def set_input_file_memory(self) -> None:
325346 """
326347 Set the input_file_memory attribute.
327348 """
328- # Molpro's memory is per cpu core and in MW (mega word; 1000 MW = 7.45 GB on a 64-bit machine)
329- # The conversion from mW to GB was done using this (https://deviceanalytics.com/words-to-bytes-converter/)
330- # specifying a 64-bit architecture.
331- #
332- # See also:
333- # https://www.molpro.net/pipermail/molpro-user/2010-April/003723.html
334- # In the link, they describe the conversion of 100,000,000 Words (100Mword) is equivalent to
335- # 800,000,000 bytes (800 mb).
336- # Formula - (100,000,000 [Words]/( 800,000,000 [Bytes] / (job mem in gb * 1000,000,000 [Bytes])))/ 1000,000 [Words -> MegaWords]
337- # The division by 1E6 is for converting into MWords
338- # Due to Zeus's configuration, there is only 1 nproc so the memory should not be divided by cpu_cores.
339- self .input_file_memory = math .ceil (self .job_memory_gb / (7.45e-3 * self .cpu_cores )) if 'zeus' not in socket .gethostname () else math .ceil (self .job_memory_gb / (7.45e-3 ))
340-
349+ # Molpro's memory is per cpu core, but here we ask for Total memory.
350+ # Molpro measures memory in MW (mega word; 1000 MW = 7.45 GB on a 64-bit machine)
351+ # The conversion from mW to GB was done using https://www.molpro.net/manual/doku.php?id=general_program_structure#memory_option_in_command_line
352+ # 3.2 GB = 100 mw (case sensitive) total (as in this implimentation) -> 31.25 mw/GB is the conversion rate
353+ self .input_file_memory = math .ceil (self .job_memory_gb * 31.25 )
354+
341355 def execute_incore (self ):
342356 """
343357 Execute a job incore.
0 commit comments