<script>
function enableGpu() {
var queue = document.getElementById("queue").value;
var gpuSpec = document.getElementById("gpuSpec");
if ( queue == "gpu" ) {
gpuSpec.innerHTML = `
<legend>
<span>GPGPU and cores</span>
</legend>
<div class="radio">
<input class="radio" type="radio" name="numGpu" id="gpu1" value="1" checked>
<label for="gpu1">1 GPGPU + 24 cores per node</label>
</div>
<div class="radio">
<input class="radio" type="radio" name="numGpu" id="gpu2" value="2">
<label for="gpu2">2 GPGPU + 48 cores per node</label>
</div>
<div class="description">
Number of GPGPU needed. Each of them has 24 cores associated.
</div>`;
document.getElementById("numCoresField").hidden = true;
} else {
gpuSpec.innerHTML = "";
document.getElementById("numCoresField").hidden = false;
}
}
function checkProgram() {
var softwareFiles = document.getElementById("softwareFiles");
var programName = document.getElementById("program").value;
softwareFiles.innerHTML = "";
switch (programName) {
case 'amber':
files=[{
class: "inputFile",
title: "Input file (-i)",
label: "Input file (-i)",
default:"mdin",
flag: "-i",
info: "Contains control data for the min/md run."
},
{ class: "inputFile",
title: "Input file (-p)",
label: "Input file (-p)",
default:"pmrtop",
flag: "-p",
info: "Contains molecular topology, force field, periodic box type, atom and residue names."
},
{ class: "inputFile",
title: "Input file (-c)",
label: "Input file (-c)",
default:"inpcrd",
flag: "-c",
info: "Contains initial coordinates and (optionally) velocities and periodic box size."
},
{ class: "outputFile",
title: "Output file (-r)",
label: "Output file (-r)",
default:"restrt",
flag: "-r",
info: "Contains final coordinates, velocity, and box dimensions for restarting run."
},
{ class: "outputFile",
title: "Output file (-o)",
label: "Output file (-o)",
default:"mdout",
flag: "-o",
info: "Contains user readable state info and diagnostics."
},
{ class: "outputFile",
title: "Output file (-x)",
label: "Output file (-x)",
default:"mdcrd",
flag: "-x",
info: "Contains coordinate sets saved over trajectory."
},
{ class: "outputFile",
title: "Output file (-e)",
label: "Output file (-e)",
default:"mden",
flag: "-e",
info: "Contains extensive energy data over trajectory (not synchronized with mdcrd or mdvel)."
},
{ class: "outputFile",
title: "Output file (-inf)",
label: "Output file (-inf)",
default:"mdinfo",
flag: "-inf",
info: "Contains Latest mdout-format energy info."
}];
break;
case 'gamess':
files=[{
class: "inputFile",
title: "Input file",
label: "Input file",
default:"gamess_input",
flag: "",
info: "Without extension."
}];
break;
case 'gaussian':
files=[{
class: "inputFile",
title: "Input file",
label: "Input file",
default:"in.com",
flag: "",
info: "Usually a <strong><em>.com<strong><em> file."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"out.log",
flag: "",
info: "Usually a <strong><em>.log<strong><em> file."
}];
break;
case 'gromacs':
files=[{
class: "inputFile",
title: "Input file (-s)",
label: "Input file (-s)",
default:"in.tpr",
flag: "-s",
info: "For <strong><em>mdrun</em></strong>, contains the topology of the system. Valid extensions: <strong><em>.tpr .tpb .tpa</strong></em>"
},
{ class: "outputFile",
title: "Output file (-g)",
label: "Output file (-g)",
default:"out.log",
flag: "-g",
info: "For <strong><em>mdrun</em></strong>, valid extension: <strong><em>.log</strong></em>"
},
{ class: "outputFile",
title: "Output file (-o)",
label: "Output file (-o)",
default:"out.trr",
flag: "-o",
info: "For <strong><em>mdrun</em></strong>, contains coordinates, velocities and optionally forces. Valid extensions: <strong><em>.trr .cpt .trj .tng</strong></em>"
},
{ class: "outputFile",
title: "Output file (-c)",
label: "Output file (-c)",
default:"out.gro",
flag: "-c",
info: "For <strong><em>mdrun</em></strong>, contains the coordinates and velocities of last step. Valid extensions: <strong><em>.gro .g96 .pdb .brk .ent .esp</strong></em>"
},
{ class: "outputFile",
title: "Output file (-e)",
label: "Output file (-e)",
default:"out.edr",
flag: "-e",
info: "For <strong><em>mdrun</em></strong>, contains energies, temperature, pressure, etc. Valid extension: <strong><em>.edr</strong></em>"
}];
break;
case 'lammps':
files=[{
class: "inputFile",
title: "Input file",
label: "Input file",
default:"input.in",
flag: "",
info: ""
}];
break;
case 'orca':
files=[{
class: "inputFile",
title: "Input file",
label: "Input file",
default:"example.inp",
flag: "",
info: "Usually a <strong><em>.inp<strong><em> file."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"example.out",
flag: "",
info: "Usually a <strong><em>.out<strong><em> file."
}];
break;
case 'siesta':
files=[{
class: "inputFile",
title: "Input file",
label: "Input file",
default:"in.com",
flag: "",
info: "Usually a <strong><em>.com<strong><em> file."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"out.log",
flag: "",
info: "Usually a <strong><em>.log<strong><em> file."
}];
break;
case 'vasp':
files=[{
class: "inputFile",
title: "Input file",
label: "Input file",
default:"INCAR",
flag: "",
info: "It holds the input parameters for the calculation.</em>"
},
{ class: "inputFile",
title: "Input file",
label: "Input file",
default:"POSCAR",
flag: "",
info: "It contains the information on the structure."
},
{ class: "inputFile",
title: "Input file",
label: "Input file",
default:"KPOINTS",
flag: "",
info: "It determines the sampling of the 1st Brillouin zone."
},
{ class: "inputFile",
title: "Input file",
label: "Input file",
default:"POTCAR",
flag: "",
info: "It contains the relevant information concerning the pseudo potentials that are necessary to run the calculation."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"OUTCAR",
flag: "",
info: "It gives detailed output of a VASP run."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"OSZICAR",
flag: "",
info: "It gives a short summary of the results."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"CONTCAR",
flag: "",
info: "It gives the updated geometry at the end of the run."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"XDATCAR",
flag: "",
info: "It contains updated ionic positions of each ionic step."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"DOSCAR",
flag: "",
info: "It contains the total and integrated DOS and optionally the local partial DOS."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"CHGCAR",
flag: "",
info: "It contains the charges p*V."
},
{ class: "outputFile",
title: "Output file",
label: "Output file",
default:"WAVECAR",
flag: "",
info: "It contains the wave function coefficients. It can be used to continue from a previous run."
}];
break;
default:
return;
break;
};
for ( file of files ) {
softwareFiles.innerHTML = softwareFiles.innerHTML + `
<div class="field-group">
<label>
${file.label}
</label>
<input class="text ${file.class}" type="text" value="${file.default}" title="${file.title}" data-flag="${file.flag}">
<div class="description">${file.info}</div>
</div>`;
}
}
function checkForm() {
if ( program.value == "—" ) {
var myFlag = AJS.flag({
close: 'auto',
type: 'error',
title: 'ERROR: FIELD REQUIRED',
body: '<p>Please, select a program.</p>'
});
program.focus();
return false;
}
if ( !jobName.value ) {
var myFlag = AJS.flag({
close: 'auto',
type: 'error',
title: 'ERROR: FIELD REQUIRED',
body: '<p>Please, type a job name.</p>'
});
document.getElementById("jobName").focus();
return false;
}
if ( ( calculTimeDays.value + calculTimeHours.value + calculTimeMinutes.value ) == 0 ) {
var myFlag = AJS.flag({
close: 'auto',
type: 'error',
title: 'ERROR: FIELD REQUIRED',
body: '<p>Please, Specify a job\'s time limit.</p>'
});
document.getElementById('calculTimeDays').focus();
return false;
}
return true;
}
function generateScript() {
var jobName = document.getElementById("jobName").value;
var program = document.getElementById("program");
var programName = program.value;
var calculTimeDays = parseInt(0 + document.getElementById('calculTimeDays').value);
var calculTimeHours = parseInt(0 + document.getElementById('calculTimeHours').value);
var calculTimeMinutes = parseInt(0 + document.getElementById('calculTimeMinutes').value);
if( !checkForm() ) return false;
// Directories and files
var directoriesText = "";
var workDir = document.getElementById("workDir").value || '${SLURM_SUBMIT_DIR}';
var inputFiles = [];
var outputFiles = [];
if ( document.getElementsByClassName("inputFile") ) {
inputFiles = document.getElementsByClassName("inputFile");
var inputFilesNames = [];
for ( var i = 0; i < inputFiles.length; i++ ) {
inputFilesNames.push(inputFiles[i].value);
}
};
if ( document.getElementsByClassName("outputFile") ) {
outputFiles = document.getElementsByClassName("outputFile");
var outputFilesNames = [];
for ( var i = 0; i < outputFiles.length; i++ ) {
outputFilesNames.push(outputFiles[i].value);
}
};
var userMail = document.getElementById("userMail").value;
var mailText = "";
var queue = document.getElementById("queue").value;
var numNodes = document.getElementById("numNodes").value;
var numCores = document.getElementById("numCores").value;
var numTasks = document.getElementById("numTasks").value;
var numThreads = document.getElementById("numThreads").value;
//var memory = document.querySelector("input[name='memOptions']:checked").value;
var ompText = "";
var programVersion = program.options[program.selectedIndex].getAttribute('data-version');
if ( numTasks > 1 ) {
numCores = numTasks;
}
// Job name
jobNameText = '\n#SBATCH -J ' + jobName
+ '\n#SBATCH -e ' + jobName + '.%j.err'
+ '\n#SBATCH -o ' + jobName + '.%j.out';
// Mail preferences
var mailEvents = document.querySelectorAll("input[name='mailEvent']:checked");
var mailType = '';
if (userMail) {
if ( mailEvents.length == 0 ) {
mailType = 'NONE ';
} else {
for (var i = 0; i < mailEvents.length; i++) {
mailType += mailEvents[i].value + ',';
}
}
mailType = mailType.slice(0,-1);
mailText = "\n#SBATCH --mail-user=" + userMail
+ "\n#SBATCH --mail-type=" + mailType;
}
// Where to submit (partition)
var whereText = '\n#SBATCH -p ' + queue;
// Resources and specs
var resourcesText = '';
if ( numNodes > 0 ) {
resourcesText += '\n#SBATCH -N ' + numNodes;
}
if ( programName == "gaussian" ) {
resourcesText += '\n#SBATCH -n 1'
+ '\n#SBATCH -c ' + numCores;
} else if ( queue == "gpu" ) {
var numGpu = document.querySelector("input[name='numGpu']:checked").value;
resourcesText += '\n#SBATCH --gres=gpu:' + numGpu;
resourcesText += '\n#SBATCH -N ' + Math.max(numNodes, 1);
numCores = numGpu * 24;
} else {
resourcesText += '\n#SBATCH --ntasks=' + Math.max(numCores, 1);
}
if ( numThreads > 1 ) {
resourcesText += '\n#SBATCH --cpus-per-task=' + numThreads;
ompText = '\n\nexport OMP_NUM_THREADS=' + numThreads;
}
/* switch ( memory ) {
case 'memStdFat':
resourcesText += '\n#SBATCH --mem-per-core=7900'
+ '\n#SBATCH -C mem';
break;
case 'memMem':
resourcesText += '\n#SBATCH --mem-per-core=15000';
break;
default:
break;
}
*/
resourcesText += '\n#SBATCH --time=' + calculTimeDays
+ '-' + calculTimeHours;
+ ':' + calculTimeMinutes;
// Charge modules and run
var modules = '\n\nmodule load apps/'
+ programName + '/' + programVersion + "\n";
var extraModulesText = '';
var runCommand = '';
directoriesText = '\n##\n# Modify the input and output files!';
switch (programName) {
case 'amber':
var executable = "pmemd";
directoriesText += '\nINPUT_FILES=$(ls ${SLURM_SUBMIT_DIR}/'
+ inputFilesNames[0] + ','
+ inputFilesNames[1] + ','
+ inputFilesNames[2] + ')';
if ( queue == "gpu" ) {
executable += ".cuda";
}
if ( numCores > 1 ) {
executable = "mpirun -np " + numCores + " " + executable + ".MPI";
}
runCommand = executable + ' -O'
+ ' -i ' + inputFilesNames[0]
+ ' -p ' + inputFilesNames[1]
+ ' -c ' + inputFilesNames[2]
+ ' -r ' + outputFilesNames[0]
+ ' -o ' + outputFilesNames[1]
+ ' -x ' + outputFilesNames[2]
+ ' -e ' + outputFilesNames[3]
+ ' -inf ' + outputFilesNames[4];
break;
case 'conda':
//directoriesText = '';
runCommand = '\n\n# Check the available conda environments with "conda env list".'
+ '\nconda activate <your_environment>';
break;
case 'gaussian':
directoriesText += '\nINPUT_FILES=' + workDir + '/' + inputFilesNames[0]
+ '\nOUTPUT_FILES=' + workDir + '/' + outputFilesNames[0];
runCommand = '\n\nsrun ' + programVersion.substr(0, 3) + ' < ' + inputFilesNames[0] + ' > ' + outputFilesNames[0];
break;
case 'gromacs':
directoriesText += '\nINPUT_FILES=' + workDir + '/' + inputFilesNames[0]
+ '\nOUTPUT_FILES=' + workDir + '/{' + outputFilesNames.join() + '}';
runCommand = '\n\n#Gromacs has multiple programs and options.\n#Go to the reference manual for more information.\n';
if ( numCores > 1 || numTasks > 1 ) {
runCommand += 'mpirun -np ' + numCores + ' gmx_mpi mdrun';
} else {
runCommand += 'gmx mdrun';
}
runCommand += ' -s ' + inputFilesNames[0]
+ ' -g ' + inputFilesNames[1]
+ ' -o ' + inputFilesNames[2]
+ ' -c ' + inputFilesNames[3]
+ ' -e ' + inputFilesNames[4];
break;
case 'lammps':
runCommand = 'mpirun -np ' + numCores + ' lmp_mpi -in '+ inputFilesNames[0];
break;
case 'namd':
runCommand = 'namd2 +p4 '
+ inputFile + '.namd > '
+ inputFile + '.out';
break;
case 'nwchem':
runCommand = 'mpijob nwchem '
+ inputFile + '.in > '
+ inputFile + '.out';
break;
case 'orca':
runCommand = '`which orca` ' + inputFilesNames[0] + ' > ' + outputFilesNames[0];
directoriesText += '\nINPUT_FILES=$(ls ${SLURM_SUBMIT_DIR}/' + inputFilesNames[0] + ')';
break;
case 'R':
runCommand = 'Rscript '
+ inputFile + '.R > '
+ inputFile + '.out';
break;
case 'siesta':
directoriesText += '\nINPUT_FILES=$(ls ${SLURM_SUBMIT_DIR}/' + inputFilesNames[0] + ')';
runCommand = 'siesta < ' + inputFilesNames[0] + ' > ' + outputFilesNames[0];
break;
case 'vasp':
directoriesText += '\nINPUT_FILES=' + workDir + '/' + inputFilesNames.join() + '})'
+ '\nOUTPUT_FILES=' + workDir + '/{' + outputFilesNames.join() + '}';
runCommand = '\n\nsrun `which vasp_std`';
extraModulesText = '\nulimit -s unlimited';
break;
default:
modules = "\n\n# Load here the modules you require";
runCommand = "# Type here the execution command";
break;
}
var modulesText = modules + extraModulesText;
var output = outputFilesNames.join();
if ( outputFilesNames.length > 1 ) {
output = '{' + output + '}';
}
var calculationText = directoriesText
+ '\n\n##'
+ '\n# You don\'t need to modify nothing more'
+ '\ncp -r ${INPUT_FILES} ${SCRATCH}'
+ '\ncd ${SCRATCH}'
+ runCommand
+ '\n\ncp ' + output + ' ' + workDir;
/*if ( stayDirectories ) {
calculationText = directoriesText + '\n##'
+ '\n# You don\'t need to modify nothing more\n'
+ runCommand;
}*/
document.getElementById('scriptText').value = '#!/bin/bash'
+ jobNameText
+ mailText
+ whereText
+ resourcesText
+ modulesText
+ ompText
+ calculationText;
var myFlag = AJS.flag({
close: 'auto',
type: 'success',
title: 'GENERATED',
body: '<p>Script generated succesfully!</p>'
});
}
function copyScript() {
var scriptText = document.getElementById('scriptText');
scriptText.select();
document.execCommand('copy');
var myFlag = AJS.flag({
close: 'auto',
type: 'success',
title: 'COPIED',
body: '<p>Script copied succesfully!</p>'
});
}
function downloadScript() {
var jobName = document.getElementById("jobName").value;
if (!jobName) {
jobName = "default";
}
var text = document.getElementById('scriptText').value;
var filename = jobName + ".slm";
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function resetScript() {
document.getElementById('scriptText').value = "";
}
//AJS.$(document).on('click', '#generateButton', generateScript);
document.getElementById('generateButton').addEventListener('click', generateScript);
document.getElementById('downloadButton').addEventListener('click', downloadScript);
document.getElementById('resetButton').addEventListener('click', resetScript);
document.getElementById('copyButton').addEventListener('click', copyScript);
</script> |