Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Fill the following form to generate a script submission file.



HTML
<style>
  #separator {
    width: 15%;
  }
  .cust-block {
    border: 1px solid #ccc;
    border-radius: 3px;
    padding: 20px;
    margin-top: 10px !important;
  }
  .tabs-pane.cust-block {
    margin-top: 0px !important;
  }
  #scriptText {
    border: none;
    resize: none;
  }
  #generateButton {
    margin-top: 10px;
  }
</style>
HTML
<div class="aui-group aui-group-split" style="padding: 0 5%;">
  <div class="aui-item">
    <form class="aui formulari">
      <h2>Required information</h2>
      <div class="cust-block">
      <!-- Program Selection -->
        <h3>Software information</h3>
        <div class="field-group">
          <label class="inputTitle">
            Select the program
            <span class="aui-icon icon-required">required</span>
          </label>
          <select class="select required" id="program" name="program" onchange="checkProgram()">
            <option selected disabled>—</option>

            <!--<optgroup label="CONDA">
              <option value="conda" data-version="3">Conda Python 3.7</option>
            </optgroup>-->
            <optgroup label="GAUSSIAN">
              <option value="gaussian" data-version="g16b1">Gaussian 16 rev. B.01</option>
              <option value="gaussian" data-version="g09e1">Gaussian 09 rev. E.01</option>
            </optgroup>
            <optgroup label="GROMACS">
              <option value="gromacs" data-version="2018.1">Gromacs 2018.1</option>
              <option value="gromacs" data-version="2019.1">Gromacs 2019.1</option>
            </optgroup>
            <optgroup label="VASP">
              <option value="vasp" data-version="5.4.4">Vasp 5.4.4</option>
            </optgroup>
            <optgroup label="—————————">
              <option value="other">—— Other software ——</option>
            </optgroup>

          </select>
          <div class="description">
            A full list of the available software can be found 
            <strong><a target="_blank" href="https://confluence.csuc.cat/display/HPCKB/Installed+software">here</a></strong>.
          </div>
          <div class="field-group">
        
          </div>
        </div>

        <!-- Files and directories -->

        <div class="field-group">
          <label for="jobName">
            Job name
            <span class="aui-icon icon-required">required</span>
          </label>
          <input class="text required" type="text" id="jobName" title="Job name" data-aui-validation-field data-aui-validation-required="required">
          <div class="description">
            Specify a name for the job allocation. 
            The specified name will appear along with the job id number when querying running jobs on the system with the 
            <a href="https://confluence.csuc.cat/display/HPCKB/squeue" target="_blank"><strong><em>squeue</em></strong></a> command .
          </div>
        </div>

        <div class="field-group">
          <label for="workDir">
            Working directory
          </label>
          <input class="text" type="text" id="workDir" title="Working directory path">
          <div class="description">
            Absolute path. Output files will be copied there.
          </div>
        </div>

        <div id="softwareFiles">
        </div>

        <div class="field-group">
          <label for="calculTime">
            Job's time limit
            <span class="aui-icon icon-required">required</span>
          </label>          
          <input class="text short-field" min="0" value="00" type="number" id="calculTimeDays" title="Days" data-aui-validation-field>-
          <input class="text short-field" min="0" max="23" value="00" type="number" id="calculTimeHours" title="Hours" data-aui-validation-field>:
          <input class="text short-field" min="0" max="59" value="00" type="number" id="calculTimeMinutes" title="Minutes" data-aui-validation-field>
          <div class="description">
            Set a run time limit (dd-hh:mm).
          </div>
        </div>
      </div>
    </form>
 
    <form class="aui formulari">
      <h2>Extra information</h2>
      <div class="aui-tabs horizontal-tabs">
        <ul class="tabs-menu">
          <li class="menu-item active-tab">
            <a href="#simple-configuration">Simple</a>
          </li>
          <li class="menu-item">
            <a href="#advanced-configuration">Advanced</a>
          </li>
        </ul>
        <div class="tabs-pane active-pane cust-block" id="simple-configuration">
        
<!-- Mail preferences -->
          <div class="field-group">
            <label for="userMail">
              Email notifications
            </label>
            <input class="text" type="email" id="userMail" title="Mail addres" placeholder="Blank to avoid notifications">
            
            <div class="aui-group">
              <div class="checkbox aui-item">
                <input class="checkbox" type="checkbox" name="mailEvent" id="mailEventBegin" value="BEGIN" checked>
                <label for="mailEventBegin">Begin</label>
              </div>
              <div class="checkbox aui-item">
                <input class="checkbox" type="checkbox" name="mailEvent" id="mailEventEnd" value="END" checked>
                <label for="mailEventEnd">End</label>
              </div>
              <div class="checkbox aui-item">
                <input class="checkbox" type="checkbox" name="mailEvent" id="mailEventFail" value="FAIL" checked>
                <label for="mailEventFail">Fail</label>
              </div>
            </div>
            <div class="description">
                Email address where to receive notifications about changes on job's state.
            </div>
          </div>
         
<!-- Where to submit the job --> 
          <div class="field-group">
            <label for="queue">
              Partition (queue)
            </label>
            <select class="select" id='queue' name='queue' onchange="enableGpu()">
              <option value="std" selected>Standard (std)</option>
              <option value="std-fat">Standard with Fat-Nodes (std-fat)</option>
              <option value="mem">Memory (mem)</option>
              <option value="gpu">GPGPU (gpu)</option>
              <option value="knl">Knights Landing (knl)</option>
            </select>
            <div class="description">
              <strong>std: </strong>The default queue. Jobs requires less memory than 3900 MB/core</br>
              <strong>std-fat: </strong>Jobs requires between 3900 MB and 7900 MB of memory per core.</br>
              <strong>mem: </strong>Jobs requires between 7900 MB and 24180 MB of memory per core. <em>(Acces Restricted)</em>.</br>
              <strong>gpu: </strong>Job requires the use of P100 Nvidia GPGPU. <strong>(Acces Restricted)</strong>.</br>
              <strong>knl: </strong>Job requires the use the 2nd Generation Intel® Xeon Phi™ Processor (Knights Landing). <strong>(Acces Restricted)</strong>.</br>
            </div>
          </div>

<!-- Job's requirements -->
          <fieldset class="group" id="gpuSpec">
          </fieldset>

          <div id="numCoresField" class="field-group">
            <label for="numCores">
              <span>Number of cores</span>
            </label>
            <input class="text short-field" min="1" max="48" value="1" type="number" id="numCores" title="Number of cores">
            <div class="description">
              Number of cores needed for parallel jobs.
            </div>
          </div>
        </div>

        <div class="tabs-pane cust-block" id="advanced-configuration">
          <div class="field-group">
            <label for="numNodes">
              <span>Number of nodes</span>
            </label>
            <input class="text short-field" min="0" max="49" value="0" type="number" id="numNodes" title="Number of nodes">
            <div class="description">
              Total number of requested nodes. Set a "0" value to let SLURM assign the minimum number of nodes (only in the generator). 
            </div>
          </div>

          <div class="field-group">
            <label for="numTasks">
              <span>MPI processes</span>
            </label>
            <input class="text short-field" min="1" max="48" value="1" type="number" id="numTasks" title="Number of processes">
            <div class="description">
              Total number of MPI processes for parallel execution.
            </div>
          </div>

          <div class="field-group">
            <label for="numThreads">
              <span>Threads OMP</span>
            </label>
            <input class="text short-field" min="1" max="48" value="1" type="number" id="numThreads" title="Number of threads per task">
            <div class="description">
              Number of OMP threads per task for parallel execution.
            </div>
          </div>

        <!--  <fieldset class="group">
            <legend>
              <span>Memory</span>
            </legend>
            <div class="radio">
              <input class="radio" type="radio" checked="checked" name="memOptions" id="memStdThin" value="memStdThin">
              <label for="memStdThin">< 4 GB</label>
            </div>
            <div class="radio">
              <input class="radio" type="radio" name="memOptions" id="memStdFat" value="memStdFat">
              <label for="memStdFat">≥ 4 GB and < 8 GB</label>
            </div>
            <div class="radio">
              <input class="radio" type="radio" name="memOptions" id="memMem" value="memMem">
              <label for="memMem">≥ 8 GB</label>
            </div>
            <div class="description">
              Amount of memory that job needs.
            </div>
          </fieldset> -->

        </div>
      </div>
      <div id='generateButton' class='aui-button aui-button-primary'>
        <span class="aui-icon aui-icon-small aui-iconfont-code">Generate script</span>
        Generate
      </div>
    </form>
  </div>

  <div id="separator" class="aui-item"></div>
  <div class="aui-item">
    <form class="aui top-label script">
      <h2>Generated Script</h2>
      <div class="field-group cust-block">
        <textarea id="scriptText" class="textarea full-width-field" rows="20" name="scriptText"></textarea>
      </div>
      <div class="aui-group aui-group-split">
        <div class="aui-item aui-buttons">
          <div id='downloadButton' class='aui-button aui-button-primary'>
            <span class="aui-icon aui-icon-small aui-iconfont-download">Download script</span>
            Download
          </div>
     
          <div id='copyButton' class='aui-button'>
            <span class="aui-icon aui-icon-small aui-iconfont-copy-clipboard">Copy</span>
            Copy
          </div>
        </div>
        <div class="aui-item">
          <div id='resetButton' class='aui-button aui-button-subtle'>
            <span class="aui-icon aui-icon-small aui-iconfont-delete">Reset script</span>
            Reset
          </div>
        </div>
      </div>
    </form>
  </div>
</div>
HTML
<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>