# batch execution for automation

In some use cases, it may be convenient to run parametric analysis of some numerical model with different parameters. A batch execution procedure may be required to automate the process. In this example, we show how to perform similar tasks. The model can be [downloaded](https://github.com/TLCFEM/suanPan-manual/blob/dev/docs/Example/Miscellaneous/batch-execution.zip).

It must be noted that by default, all output files generated by recorders are saved under the current working folder. Only the [Visualization](https://tlcfem.gitbook.io/suanpan-manual/recorder/recorder) recorder supports customized output folder name, which is again defined relative to current working folder.

Possible useful commands include: [`pwd`](https://tlcfem.gitbook.io/suanpan-manual/command-collection/process/pwd) , [`terminal`](https://github.com/TLCFEM/suanPan-manual/blob/dev/docs/Collection/Process/terminal.md). Depending on the different platform, it is always possible to use PowerShell, bash or other shells to perform automation tasks. Here, we show a Python example.

## Batched Time History Analysis

Suppose we, as structural engineers, are asked to perform a series of time history analyses to find the maximum displacement of some structure under a number of different ground motions.

For simplicity, let the structure be a SDOF mass--spring system, and we want to apply all the records in the [NZ Strong Motion](https://tlcfem.gitbook.io/suanpan-manual/amplitude/special/nzstrongmotion) database. Please note the provided archive only contains a few records. Please visit the corresponding page for the full database (with 700+ records).

### The Model

We define a template of the model and use a placeholder named as `$groundMotionRecord` to be later replaced by specific record names. The analysis time is labelled as `$duration`. It can be changed for different records. The model script will look like the follows.

```
# an example of batch processing

node 1 0 0
node 2 1 0

# set modulus ==> 16\pi^2
material Elastic1D 1 157.913670417

element T2D2 1 1 2 1 1

mass 2 2 1 1

fix 1 1 1
fix 2 2 1 2

amplitude NZStrongMotion 1 $groundMotionRecord

# apply reference acceleration ==> 1m/s^2
acceleration 2 1 1.0 1 2

hdf5recorder 1 Node U1 2

step dynamic 1 $duration
set ini_step_size 1E-2
set fixed_step_size true

integrator Newmark 1

converger AbsIncreDisp 1 1E-12 10 1

analyze

exit
```

The above model defines a SDOF structure with a period of half a second. With PGA equals unity (ground motion record is normalised), the displacement is recorded.

### Folder Structure

The template model file `batch-execution.supan` is placed alongside the folder `NZStrongMotion` which contains example NZ strong motion records.

```ps
C:\BATCH-EXECUTION
│   batch-execution.supan
│
└───NZStrongMotion
    20030821_121249_BDCS_N59E_A
    20030821_121249_BDCS_S31E_A
    20030821_121249_DCDS_N67E_A
    20030821_121249_DCDS_S23E_A
    20030821_121249_DGNS_S18W_A
    20030821_121249_DGNS_S72E_A
    20030821_121249_DKHS_N33W_A
```

To automate the task, we want to

1. loop over all strong motion records
2. for each record, replace placeholder `$groundMotionRecord` with the proper file name to load the record
3. replace `$duration` with proper analysis duration which can be determined by the duration of record
4. perform the response history analysis

Note the recorded displacement is stored in `*.h5` file, it may be better to store them in different folder with the name of the corresponding ground motion. This can be done in two approaches:

1. Create the folder first and launch `suanPan` inside that folder.
2. Launch `suanPan` first, use `terminal` to create that folder, switch to that folder via `pwd` and perform the analysis.

Given that we are going to use Python, we can simply choose the first option.

### Python Script

#### Load Template First

```py
import os
import shutil

placeholder = '$groundMotionRecord'
duration = '$duration'

template_file = open("batch-execution.supan", "r")
template_model = template_file.read()
```

#### Load All Record Names

```py
records = os.listdir('NZStrongMotion')
```

#### Loop

Now loop over each record and perform the analysis.

```py
for record in records:
    print("Processing " + record)
    try:
        # try to create folder
        os.mkdir(record)
    except OSError:
        # if folder exists, remove it and create an empty one
        shutil.rmtree(record)
        os.mkdir(record)
    # switch to the created folder
    os.chdir(record)
    # create the model file by using the record name
    model_file = open(record + ".sp", "w")
    # write modified script to the model file
    # remember now we are in the newly created folder, the record is stored in ..\NZStrongMotion
    model_file.write(template_model.replace(placeholder, '..\\NZStrongMotion\\' + record).replace(duration, '100'))
    # remember to close before running the model
    model_file.close()
    # now invoke suanPan to run the model
    # you may need to replace suanPan with the full path to the executable file if it is not added to PATH
    os.system('suanPan -f ' + record + '.sp > log.txt')
    # need to change back to parent folder
    os.chdir('..')
```

### Postprocessing

What if to postprocessing data? Since the output files are stored in `HDF5` format, one can use `h5py` to operate on those results to do whatever needed.
