# MEQ - Matlab Equilibrium Toolbox

**A suite of codes for tokamak equilibrium calculations.**

*Swiss Plasma Center EPFL Lausanne 2022. All rights reserved*

Originally based on `FBT` and `LIUQE` codes written for the TCV tokamak in `FORTRAN` by F. Hoffmann and others (CRPP-EPFL Lausanne). See [1],[2],[3].

Re-written in `MATLAB` by Jean-Marc Moret, including real-time application on the TCV Tokamak [4]

Presently maintained on https://gitlab.epfl.ch/spc/tcv/tbx/meq

Code suite maintainers: 

* [Antoine Merle](mailto:antoine.merle@epfl.ch)
* [Federico Felici](mailto:federico.felici@epfl.ch)

Table of contents:

[[_TOC_]]

## Installation

To install for the first time, first ask the maintainers for access to both `meq` and `genlib` toolboxes. 
### Get the code
```
# Clone, e.g.
git clone git@gitlab.epfl.ch:spc/tcv/tbx/meq meq
# initialize and update submodules
git submodule update --init --recursive
```

### Build

`meq` is built using the `make` command. The default `all-nort` target  builds all necessary binaries to successfuly run the test suite including for the Simulink models. It is highly recommended to provide the path to the root directory of the MATLAB installation using the `MATPATH` variable. Other commonly used variables to customize the build are `CC` to choose the C compiler and `BLASLIB` to choose the source of the BLAS and LAPACK libraries (see below for a more detailed description).

For example the following line builds `meq` with GCC and the MATLAB-provided version of BLAS and LAPACK.

```
# make meq
make all-nort CC=gcc MATPATH=<path_to_matlab_root_directory>
```
#### General makefile options

`meq` makefile targets:

* `tbx` (`mex`es, for `.m` use only)
* `doc` (documentation)
* `all` (includes Simulink S functions, rt library, and genlib)
* `all-nort` (same as `all` but excluding the rt library, this is the default target)

`meq`/`genlib` makefile options:

* `CC`: Compiler (`gcc` or `icc`, default is `icc`)
* `CCRT`: Compiler for real-time version
* `MATPATH`: root directory of the `MATLAB` installation, e.g. `/usr/local/MATLAB/R2022b` (if you don't know but can open MATLAB, use the `matlabroot` command to find out).  
* `BLASLIB`: Default links to `MATLAB`-supplied MKL. Otherwise specify `MKL` or `CBLAS` (tested with OpenBlas on OSX)
* `BUILD`: `optimized` (default) or `debug` (allows debugging of MEX-files using e.g. `gdb` and prints debug information from `libmeq` routines)



#### On SPC LAC clusters 
On a machine with icc:

```
make all
```

#### On HPC ITER hpc-login.iter.org
```
# Clean existing loaded module 
#   (to avoid conflict with compiler version and matlab version)
module purge
# Load intel compiler 
module load intel/2018a
# Load matlab module
module load MATLAB
# Set environment variable for matlab root
export MATLAB=$EBROOTMATLAB
# Compile (from within meq folder)
make all
```

#### On MacOS on an ARM processor
First check the architecture with `arch`, if it is `arm` then first do:
```
$ env /usr/bin/arch -x86_64 /bin/zsh --login
```
to change the architecture. After this command, `arch` should return `i386`

If you want to use `icc` you probably need to run
```
source /opt/intel/oneapi/setvars.sh 
make CC=icc
```

If you run into issues where it can't find <math.h>, check whether the SDK is in the default place specified by Makefile.MacOS. If not, append something like
```
SYSROOT="<sysroot location>" to the make command
```

#### On a Windows machine
The windows build of MEQ is still under development. For now we recommend to have a machine with MATLAB and MSYS2 installed, and within the MSYS2-MINGW64 shell install the `make` and `git` packages as well as the `mingw-w64-x86_64-toolchain` group using the `pacman -S make git mingw-w64-x86_64-toolchain` command.

Within a MSYS2-MINGW64 shell, run the following command from the `meq` directory:
```
make MATPATH="/c/Program\ Files/MATLAB/R2022b" CC=gcc WERROR=no tbx
```

If the mex command cannot find a compiler, make sure to define the following environment variable:
```
MW_MINGW64_LOC=C:\msys64\mingw64 (or the path to your installation of mingw64)
```

It is recommended (even if probably not necessary) to install MSYS2 in a path without spaces.
Note that, in order to access tcv data, the mds module is also needed. It can be cloned and set up as follows:

```
git clone https://gitlab.epfl.ch/spc/tcv/tbx/mds.git
cd mds
git checkout am_updates
git submodule init --update --recursive
```

#### Using Octave
The Octave build of MEQ is still under development. As the MATLAB-provided versions of BLAS and LAPACK are not available, one should define the BLASLIB variable to CBLAS or MKL.

The following command allows to build the necessary MEX-files for `meq`:
```
make USE_OCTAVE=1 USE_OPENMP=no BLASLIB=CBLAS tbx
```

Note that neither the MATLAB test suite nor the Simulink models can be used within Octave.

#### Using Octave on MacOS with ARM
After setting up brew, install the required dependencies. 
Below is a list of versions that work at time of writing.

```
brew install octave@8.3.0
brew install openblas@0.3.24
brew install lapack@3.11
brew install gcc@13.2.0
```

Build `tbx`:

```
make tbx USE_OCTAVE=1 USE_OPENMP=no BLASLIB=CBLAS CC=gcc \
CBLASPATH=/opt/homebrew/opt/openblas/ LAPACKPATH=/opt/homebrew/opt/lapack/ MATPATH=/opt/homebrew/bin
```
 
### Testing

#### MATLAB

From the shell:
```
./test_script <matlab> <mytest>                   
```
`<matlab>` is the command to start MATLAB. 
For `<mytest>` see the options below.

From MATLAB
```
run_meq_tests(mytest)
```

Some `mytest` options:

* `'unit'` (run unit tests)
* `'integration'` (run integration tests)
* `'TCV'` (run tests on various TCV equilibria, requires TCV data access)
* `'CREATE'` (run tests on CREATE-supplied ITER scenarios, requires equilibrium files to be present)
* `'fgs'`,`'fge'`,`'fbt'`,`'liu'` (code specific tests)


#### Octave

From the shell:
```
./test_script octave tests_octave/meq_test.m
```

From Octave:
```
tests_octave('tests_octave/meq_test.m')
```

Note that the full MATLAB test suite is currently not available in Octave.

## Getting started
* See `documentation/Getting_started.m` for an overview of help options.
* Type `doc meq` to open `meq` documentation
* See `documentation/tutorials` for `.m` files of tutorials

## Common places to get help
* `help meqhelp` (naming schemes and general help)
* `help meqt` (output variable naming)
* [documentation/CHEATSHEET.md](documentation/CHEATSHEET.md) (geometry structure variable naming)
* `help fbt`, `help liu`, `help fge`, `help fgs`, `help rzp` for help on the high-level codes.
* `help meqp`, `help fbtp` `help liup` etc for help on the meaning of parameters

### TCV example calls (requires data access or running on SPC's lac clusters)
* Equilibrium reconstruction for TCV:
  ```
  [L,LX,LY] = liuqe(shot,time);
  ```
* Solve static inverse problem for TCV:
  ```
  [L,LY] = fbt('tcv',shot); 
  ```
* Solve forward Grad-Shafranov equation TCV:
  ```
  [L,LX,LY] = fgs('tcv',shot,time); 
  ```

## Coordinate system
MEQ uses the coordinate system defined by `COCOS=17` (see [5]).
This means: 

* Right-handed $(R,phi,Z)$ cylindrical coordinate system
* Right-handed $(\rho,\theta,phi)$ toroidal coordinate system 
* Poloidal flux [in Wb] defined as $\psi = \int B_z dS_z$.

## Basis function sets
* Currently the following basis function sets are defined
  * `bfab`  : up to 3rd degree polynomial functions for P' and TT' with zero value at the edge (MATLAB and C implementation)
  * `bfef`  : up to 3rd degree polynomial functions for P' and TT' with non-zero value at the edge (MATLAB and C implementation)
  * `bf3p`  : linear P' profile, 2nd degree polynomial TT' profile, equivalent to bfab[nP=1,nT=2] (optmized C implementation for speed)
  * `bf3i`  : linear interpolation of 3 functions defined on a regular grid of the normalized poloidal flux (C implementation only)
  * `bffbt` : legacy basis functions from the FORTRAN implementation of the FBT code, 3 basis functions consisting in a combination of real-values powers of the normalized poloidal flux (MATLAB implementation only)
  * `bfsp`  : cubic spline definitions of P' and TT', the choice of the knots is free but is common to P' and TT' (MATLAB implementation only)
  * `bfgenD`: a generic basis function set for multiple domains
* Definition of a new basis function set
  * To implement a new basis function set in MATLAB, the minimal requirements are a function to compute the value of each of the basis functions for a set values of the normalized poloidal flux and a mapping of each of the basis functions to either P' or TT'. See `bfct.m` for the detailed requirements and `bfsp.m`, `bffbt.m`, `bfab.m` or `bfef.m` for examples.
  * For a C implementation the requirements are similar. More details can be found in `bfct.c` and examples in the different `libmeq/bf??.c` files. MEX-files can be implemented using functions in `bfctmex.h` and you can find examples in the different `mexc/bf??mex.c` files.
* The main function for each set can be called with different "modes" corresponding to the different ways that they can be used in MEQ. The description of these modes can be found in `bfhelp.m`.

## Troubleshooting
* Flag bugs/feature requests here: [https://gitlab.epfl.ch/spc/tcv/tbx/meq/issues](https://gitlab.epfl.ch/spc/tcv/tbx/meq/issues)
* MEQ slack workspace: [https://meq-chat.slack.com](https://meq-chat.slack.com)

## Contributing
* Contributions to this code are welcome, whether they be bugfixes or new feature additions.
* To avoid duplication, it is strongly recommended that you first discuss the proposed modification by opening an [issue](https://gitlab.epfl.ch/spc/tcv/tbx/meq/issues)
* Please consult the file `CONTRIBUTING.md` for more information on how to contribute.
* In order to clarify ownership of the developed contribution, a contributor license agreement (CLA) is required. This is also explained in the `CONTRIBUTING.md` file.

## License
A license is required to use or modify any part of code. Please contact the code maintainers for licensing options.

## References
* [1],[2],[3],[4],[5] cited in this document: see [CITATION.md](CITATION.md).

Please consult [CITATION.md](CITATION.md) to learn how to cite MEQ-related papers when publishing scientific results that use MEQ.

