diff --git a/README.md b/README.md index 0d19ea5..b1cd92b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,18 @@ +[![CI](https://github.com/kaelyndunnell/hisp/actions/workflows/ci.yml/badge.svg)](https://github.com/kaelyndunnell/hisp/actions/workflows/ci.yml) # HISP + Hydrogen Inventory Simulations for PFCs (HISP) is a series of code that uses FESTIM to simulate deuterium and tritium inventories in a fusion tokamak first wall and divertor PFCs. ## How to Run: -First, run this in the terminal to create a new environment with the right dependencies: +Clone the repository: + +``` +git clone https://github.com/kaelyndunnell/hisp +cd hisp +``` + +Run this command to create a new environment with the right dependencies (eg. dolfinx): ``` conda env create -f environment.yml ``` @@ -13,3 +22,23 @@ Then, activate the environment: conda activate hisp-env ``` + +Install the `hisp` package with: + +``` +python -m pip install -e . +``` + +This will also install the pip dependencies like `h-transport-materials` and `FESTIM`. + +> **_NOTE:_** Using `-e` with pip will install the package in editable mode, meaning the source code can be modified without having to reinstall the package. + +## Run the tests + +After cloning the repo and installing hisp, run: + +``` +python -m pytest test +``` + +> **_NOTE:_** Make sure to install the test dependencies with `python -m pip install -e .[test]` diff --git a/Binned_Flux_Data.dat b/data/Binned_Flux_Data.dat similarity index 100% rename from Binned_Flux_Data.dat rename to data/Binned_Flux_Data.dat diff --git a/GDC_data.dat b/data/GDC_data.dat similarity index 100% rename from GDC_data.dat rename to data/GDC_data.dat diff --git a/ICWC_data.dat b/data/ICWC_data.dat similarity index 100% rename from ICWC_data.dat rename to data/ICWC_data.dat diff --git a/RISP_Wall_data.dat b/data/RISP_Wall_data.dat similarity index 100% rename from RISP_Wall_data.dat rename to data/RISP_Wall_data.dat diff --git a/RISP_data/time0.dat b/data/RISP_data/time0.dat similarity index 100% rename from RISP_data/time0.dat rename to data/RISP_data/time0.dat diff --git a/RISP_data/time10.dat b/data/RISP_data/time10.dat similarity index 100% rename from RISP_data/time10.dat rename to data/RISP_data/time10.dat diff --git a/RISP_data/time100.dat b/data/RISP_data/time100.dat similarity index 100% rename from RISP_data/time100.dat rename to data/RISP_data/time100.dat diff --git a/RISP_data/time101.dat b/data/RISP_data/time101.dat similarity index 100% rename from RISP_data/time101.dat rename to data/RISP_data/time101.dat diff --git a/RISP_data/time102.dat b/data/RISP_data/time102.dat similarity index 100% rename from RISP_data/time102.dat rename to data/RISP_data/time102.dat diff --git a/RISP_data/time103.dat b/data/RISP_data/time103.dat similarity index 100% rename from RISP_data/time103.dat rename to data/RISP_data/time103.dat diff --git a/RISP_data/time104.dat b/data/RISP_data/time104.dat similarity index 100% rename from RISP_data/time104.dat rename to data/RISP_data/time104.dat diff --git a/RISP_data/time105.dat b/data/RISP_data/time105.dat similarity index 100% rename from RISP_data/time105.dat rename to data/RISP_data/time105.dat diff --git a/RISP_data/time106.dat b/data/RISP_data/time106.dat similarity index 100% rename from RISP_data/time106.dat rename to data/RISP_data/time106.dat diff --git a/RISP_data/time107.dat b/data/RISP_data/time107.dat similarity index 100% rename from RISP_data/time107.dat rename to data/RISP_data/time107.dat diff --git a/RISP_data/time108.dat b/data/RISP_data/time108.dat similarity index 100% rename from RISP_data/time108.dat rename to data/RISP_data/time108.dat diff --git a/RISP_data/time109.dat b/data/RISP_data/time109.dat similarity index 100% rename from RISP_data/time109.dat rename to data/RISP_data/time109.dat diff --git a/RISP_data/time110.dat b/data/RISP_data/time110.dat similarity index 100% rename from RISP_data/time110.dat rename to data/RISP_data/time110.dat diff --git a/RISP_data/time111.dat b/data/RISP_data/time111.dat similarity index 100% rename from RISP_data/time111.dat rename to data/RISP_data/time111.dat diff --git a/RISP_data/time112.dat b/data/RISP_data/time112.dat similarity index 100% rename from RISP_data/time112.dat rename to data/RISP_data/time112.dat diff --git a/RISP_data/time113.dat b/data/RISP_data/time113.dat similarity index 100% rename from RISP_data/time113.dat rename to data/RISP_data/time113.dat diff --git a/RISP_data/time114.dat b/data/RISP_data/time114.dat similarity index 100% rename from RISP_data/time114.dat rename to data/RISP_data/time114.dat diff --git a/RISP_data/time115.dat b/data/RISP_data/time115.dat similarity index 100% rename from RISP_data/time115.dat rename to data/RISP_data/time115.dat diff --git a/RISP_data/time116.dat b/data/RISP_data/time116.dat similarity index 100% rename from RISP_data/time116.dat rename to data/RISP_data/time116.dat diff --git a/RISP_data/time117.dat b/data/RISP_data/time117.dat similarity index 100% rename from RISP_data/time117.dat rename to data/RISP_data/time117.dat diff --git a/RISP_data/time118.dat b/data/RISP_data/time118.dat similarity index 100% rename from RISP_data/time118.dat rename to data/RISP_data/time118.dat diff --git a/RISP_data/time119.dat b/data/RISP_data/time119.dat similarity index 100% rename from RISP_data/time119.dat rename to data/RISP_data/time119.dat diff --git a/RISP_data/time120.dat b/data/RISP_data/time120.dat similarity index 100% rename from RISP_data/time120.dat rename to data/RISP_data/time120.dat diff --git a/RISP_data/time121.dat b/data/RISP_data/time121.dat similarity index 100% rename from RISP_data/time121.dat rename to data/RISP_data/time121.dat diff --git a/RISP_data/time122.dat b/data/RISP_data/time122.dat similarity index 100% rename from RISP_data/time122.dat rename to data/RISP_data/time122.dat diff --git a/RISP_data/time123.dat b/data/RISP_data/time123.dat similarity index 100% rename from RISP_data/time123.dat rename to data/RISP_data/time123.dat diff --git a/RISP_data/time124.dat b/data/RISP_data/time124.dat similarity index 100% rename from RISP_data/time124.dat rename to data/RISP_data/time124.dat diff --git a/RISP_data/time125.dat b/data/RISP_data/time125.dat similarity index 100% rename from RISP_data/time125.dat rename to data/RISP_data/time125.dat diff --git a/RISP_data/time126.dat b/data/RISP_data/time126.dat similarity index 100% rename from RISP_data/time126.dat rename to data/RISP_data/time126.dat diff --git a/RISP_data/time127.dat b/data/RISP_data/time127.dat similarity index 100% rename from RISP_data/time127.dat rename to data/RISP_data/time127.dat diff --git a/RISP_data/time128.dat b/data/RISP_data/time128.dat similarity index 100% rename from RISP_data/time128.dat rename to data/RISP_data/time128.dat diff --git a/RISP_data/time129.dat b/data/RISP_data/time129.dat similarity index 100% rename from RISP_data/time129.dat rename to data/RISP_data/time129.dat diff --git a/RISP_data/time130.dat b/data/RISP_data/time130.dat similarity index 100% rename from RISP_data/time130.dat rename to data/RISP_data/time130.dat diff --git a/RISP_data/time131.dat b/data/RISP_data/time131.dat similarity index 100% rename from RISP_data/time131.dat rename to data/RISP_data/time131.dat diff --git a/RISP_data/time132.dat b/data/RISP_data/time132.dat similarity index 100% rename from RISP_data/time132.dat rename to data/RISP_data/time132.dat diff --git a/RISP_data/time133.dat b/data/RISP_data/time133.dat similarity index 100% rename from RISP_data/time133.dat rename to data/RISP_data/time133.dat diff --git a/RISP_data/time134.dat b/data/RISP_data/time134.dat similarity index 100% rename from RISP_data/time134.dat rename to data/RISP_data/time134.dat diff --git a/RISP_data/time135.dat b/data/RISP_data/time135.dat similarity index 100% rename from RISP_data/time135.dat rename to data/RISP_data/time135.dat diff --git a/RISP_data/time136.dat b/data/RISP_data/time136.dat similarity index 100% rename from RISP_data/time136.dat rename to data/RISP_data/time136.dat diff --git a/RISP_data/time137.dat b/data/RISP_data/time137.dat similarity index 100% rename from RISP_data/time137.dat rename to data/RISP_data/time137.dat diff --git a/RISP_data/time138.dat b/data/RISP_data/time138.dat similarity index 100% rename from RISP_data/time138.dat rename to data/RISP_data/time138.dat diff --git a/RISP_data/time139.dat b/data/RISP_data/time139.dat similarity index 100% rename from RISP_data/time139.dat rename to data/RISP_data/time139.dat diff --git a/RISP_data/time140.dat b/data/RISP_data/time140.dat similarity index 100% rename from RISP_data/time140.dat rename to data/RISP_data/time140.dat diff --git a/RISP_data/time141.dat b/data/RISP_data/time141.dat similarity index 100% rename from RISP_data/time141.dat rename to data/RISP_data/time141.dat diff --git a/RISP_data/time142.dat b/data/RISP_data/time142.dat similarity index 100% rename from RISP_data/time142.dat rename to data/RISP_data/time142.dat diff --git a/RISP_data/time143.dat b/data/RISP_data/time143.dat similarity index 100% rename from RISP_data/time143.dat rename to data/RISP_data/time143.dat diff --git a/RISP_data/time144.dat b/data/RISP_data/time144.dat similarity index 100% rename from RISP_data/time144.dat rename to data/RISP_data/time144.dat diff --git a/RISP_data/time145.dat b/data/RISP_data/time145.dat similarity index 100% rename from RISP_data/time145.dat rename to data/RISP_data/time145.dat diff --git a/RISP_data/time146.dat b/data/RISP_data/time146.dat similarity index 100% rename from RISP_data/time146.dat rename to data/RISP_data/time146.dat diff --git a/RISP_data/time147.dat b/data/RISP_data/time147.dat similarity index 100% rename from RISP_data/time147.dat rename to data/RISP_data/time147.dat diff --git a/RISP_data/time148.dat b/data/RISP_data/time148.dat similarity index 100% rename from RISP_data/time148.dat rename to data/RISP_data/time148.dat diff --git a/RISP_data/time149.dat b/data/RISP_data/time149.dat similarity index 100% rename from RISP_data/time149.dat rename to data/RISP_data/time149.dat diff --git a/RISP_data/time150.dat b/data/RISP_data/time150.dat similarity index 100% rename from RISP_data/time150.dat rename to data/RISP_data/time150.dat diff --git a/RISP_data/time151.dat b/data/RISP_data/time151.dat similarity index 100% rename from RISP_data/time151.dat rename to data/RISP_data/time151.dat diff --git a/RISP_data/time152.dat b/data/RISP_data/time152.dat similarity index 100% rename from RISP_data/time152.dat rename to data/RISP_data/time152.dat diff --git a/RISP_data/time153.dat b/data/RISP_data/time153.dat similarity index 100% rename from RISP_data/time153.dat rename to data/RISP_data/time153.dat diff --git a/RISP_data/time154.dat b/data/RISP_data/time154.dat similarity index 100% rename from RISP_data/time154.dat rename to data/RISP_data/time154.dat diff --git a/RISP_data/time155.dat b/data/RISP_data/time155.dat similarity index 100% rename from RISP_data/time155.dat rename to data/RISP_data/time155.dat diff --git a/RISP_data/time156.dat b/data/RISP_data/time156.dat similarity index 100% rename from RISP_data/time156.dat rename to data/RISP_data/time156.dat diff --git a/RISP_data/time157.dat b/data/RISP_data/time157.dat similarity index 100% rename from RISP_data/time157.dat rename to data/RISP_data/time157.dat diff --git a/RISP_data/time158.dat b/data/RISP_data/time158.dat similarity index 100% rename from RISP_data/time158.dat rename to data/RISP_data/time158.dat diff --git a/RISP_data/time159.dat b/data/RISP_data/time159.dat similarity index 100% rename from RISP_data/time159.dat rename to data/RISP_data/time159.dat diff --git a/RISP_data/time160.dat b/data/RISP_data/time160.dat similarity index 100% rename from RISP_data/time160.dat rename to data/RISP_data/time160.dat diff --git a/RISP_data/time161.dat b/data/RISP_data/time161.dat similarity index 100% rename from RISP_data/time161.dat rename to data/RISP_data/time161.dat diff --git a/RISP_data/time162.dat b/data/RISP_data/time162.dat similarity index 100% rename from RISP_data/time162.dat rename to data/RISP_data/time162.dat diff --git a/RISP_data/time163.dat b/data/RISP_data/time163.dat similarity index 100% rename from RISP_data/time163.dat rename to data/RISP_data/time163.dat diff --git a/RISP_data/time164.dat b/data/RISP_data/time164.dat similarity index 100% rename from RISP_data/time164.dat rename to data/RISP_data/time164.dat diff --git a/RISP_data/time165.dat b/data/RISP_data/time165.dat similarity index 100% rename from RISP_data/time165.dat rename to data/RISP_data/time165.dat diff --git a/RISP_data/time166.dat b/data/RISP_data/time166.dat similarity index 100% rename from RISP_data/time166.dat rename to data/RISP_data/time166.dat diff --git a/RISP_data/time167.dat b/data/RISP_data/time167.dat similarity index 100% rename from RISP_data/time167.dat rename to data/RISP_data/time167.dat diff --git a/RISP_data/time168.dat b/data/RISP_data/time168.dat similarity index 100% rename from RISP_data/time168.dat rename to data/RISP_data/time168.dat diff --git a/RISP_data/time169.dat b/data/RISP_data/time169.dat similarity index 100% rename from RISP_data/time169.dat rename to data/RISP_data/time169.dat diff --git a/RISP_data/time170.dat b/data/RISP_data/time170.dat similarity index 100% rename from RISP_data/time170.dat rename to data/RISP_data/time170.dat diff --git a/RISP_data/time171.dat b/data/RISP_data/time171.dat similarity index 100% rename from RISP_data/time171.dat rename to data/RISP_data/time171.dat diff --git a/RISP_data/time172.dat b/data/RISP_data/time172.dat similarity index 100% rename from RISP_data/time172.dat rename to data/RISP_data/time172.dat diff --git a/RISP_data/time173.dat b/data/RISP_data/time173.dat similarity index 100% rename from RISP_data/time173.dat rename to data/RISP_data/time173.dat diff --git a/RISP_data/time174.dat b/data/RISP_data/time174.dat similarity index 100% rename from RISP_data/time174.dat rename to data/RISP_data/time174.dat diff --git a/RISP_data/time175.dat b/data/RISP_data/time175.dat similarity index 100% rename from RISP_data/time175.dat rename to data/RISP_data/time175.dat diff --git a/RISP_data/time176.dat b/data/RISP_data/time176.dat similarity index 100% rename from RISP_data/time176.dat rename to data/RISP_data/time176.dat diff --git a/RISP_data/time177.dat b/data/RISP_data/time177.dat similarity index 100% rename from RISP_data/time177.dat rename to data/RISP_data/time177.dat diff --git a/RISP_data/time178.dat b/data/RISP_data/time178.dat similarity index 100% rename from RISP_data/time178.dat rename to data/RISP_data/time178.dat diff --git a/RISP_data/time179.dat b/data/RISP_data/time179.dat similarity index 100% rename from RISP_data/time179.dat rename to data/RISP_data/time179.dat diff --git a/RISP_data/time180.dat b/data/RISP_data/time180.dat similarity index 100% rename from RISP_data/time180.dat rename to data/RISP_data/time180.dat diff --git a/RISP_data/time181.dat b/data/RISP_data/time181.dat similarity index 100% rename from RISP_data/time181.dat rename to data/RISP_data/time181.dat diff --git a/RISP_data/time182.dat b/data/RISP_data/time182.dat similarity index 100% rename from RISP_data/time182.dat rename to data/RISP_data/time182.dat diff --git a/RISP_data/time183.dat b/data/RISP_data/time183.dat similarity index 100% rename from RISP_data/time183.dat rename to data/RISP_data/time183.dat diff --git a/RISP_data/time184.dat b/data/RISP_data/time184.dat similarity index 100% rename from RISP_data/time184.dat rename to data/RISP_data/time184.dat diff --git a/RISP_data/time185.dat b/data/RISP_data/time185.dat similarity index 100% rename from RISP_data/time185.dat rename to data/RISP_data/time185.dat diff --git a/RISP_data/time186.dat b/data/RISP_data/time186.dat similarity index 100% rename from RISP_data/time186.dat rename to data/RISP_data/time186.dat diff --git a/RISP_data/time187.dat b/data/RISP_data/time187.dat similarity index 100% rename from RISP_data/time187.dat rename to data/RISP_data/time187.dat diff --git a/RISP_data/time188.dat b/data/RISP_data/time188.dat similarity index 100% rename from RISP_data/time188.dat rename to data/RISP_data/time188.dat diff --git a/RISP_data/time189.dat b/data/RISP_data/time189.dat similarity index 100% rename from RISP_data/time189.dat rename to data/RISP_data/time189.dat diff --git a/RISP_data/time190.dat b/data/RISP_data/time190.dat similarity index 100% rename from RISP_data/time190.dat rename to data/RISP_data/time190.dat diff --git a/RISP_data/time191.dat b/data/RISP_data/time191.dat similarity index 100% rename from RISP_data/time191.dat rename to data/RISP_data/time191.dat diff --git a/RISP_data/time192.dat b/data/RISP_data/time192.dat similarity index 100% rename from RISP_data/time192.dat rename to data/RISP_data/time192.dat diff --git a/RISP_data/time193.dat b/data/RISP_data/time193.dat similarity index 100% rename from RISP_data/time193.dat rename to data/RISP_data/time193.dat diff --git a/RISP_data/time194.dat b/data/RISP_data/time194.dat similarity index 100% rename from RISP_data/time194.dat rename to data/RISP_data/time194.dat diff --git a/RISP_data/time195.dat b/data/RISP_data/time195.dat similarity index 100% rename from RISP_data/time195.dat rename to data/RISP_data/time195.dat diff --git a/RISP_data/time196.dat b/data/RISP_data/time196.dat similarity index 100% rename from RISP_data/time196.dat rename to data/RISP_data/time196.dat diff --git a/RISP_data/time197.dat b/data/RISP_data/time197.dat similarity index 100% rename from RISP_data/time197.dat rename to data/RISP_data/time197.dat diff --git a/RISP_data/time198.dat b/data/RISP_data/time198.dat similarity index 100% rename from RISP_data/time198.dat rename to data/RISP_data/time198.dat diff --git a/RISP_data/time199.dat b/data/RISP_data/time199.dat similarity index 100% rename from RISP_data/time199.dat rename to data/RISP_data/time199.dat diff --git a/RISP_data/time200.dat b/data/RISP_data/time200.dat similarity index 100% rename from RISP_data/time200.dat rename to data/RISP_data/time200.dat diff --git a/RISP_data/time201.dat b/data/RISP_data/time201.dat similarity index 100% rename from RISP_data/time201.dat rename to data/RISP_data/time201.dat diff --git a/RISP_data/time202.dat b/data/RISP_data/time202.dat similarity index 100% rename from RISP_data/time202.dat rename to data/RISP_data/time202.dat diff --git a/RISP_data/time203.dat b/data/RISP_data/time203.dat similarity index 100% rename from RISP_data/time203.dat rename to data/RISP_data/time203.dat diff --git a/RISP_data/time204.dat b/data/RISP_data/time204.dat similarity index 100% rename from RISP_data/time204.dat rename to data/RISP_data/time204.dat diff --git a/RISP_data/time205.dat b/data/RISP_data/time205.dat similarity index 100% rename from RISP_data/time205.dat rename to data/RISP_data/time205.dat diff --git a/RISP_data/time206.dat b/data/RISP_data/time206.dat similarity index 100% rename from RISP_data/time206.dat rename to data/RISP_data/time206.dat diff --git a/RISP_data/time207.dat b/data/RISP_data/time207.dat similarity index 100% rename from RISP_data/time207.dat rename to data/RISP_data/time207.dat diff --git a/RISP_data/time208.dat b/data/RISP_data/time208.dat similarity index 100% rename from RISP_data/time208.dat rename to data/RISP_data/time208.dat diff --git a/RISP_data/time209.dat b/data/RISP_data/time209.dat similarity index 100% rename from RISP_data/time209.dat rename to data/RISP_data/time209.dat diff --git a/RISP_data/time210.dat b/data/RISP_data/time210.dat similarity index 100% rename from RISP_data/time210.dat rename to data/RISP_data/time210.dat diff --git a/RISP_data/time211.dat b/data/RISP_data/time211.dat similarity index 100% rename from RISP_data/time211.dat rename to data/RISP_data/time211.dat diff --git a/RISP_data/time212.dat b/data/RISP_data/time212.dat similarity index 100% rename from RISP_data/time212.dat rename to data/RISP_data/time212.dat diff --git a/RISP_data/time213.dat b/data/RISP_data/time213.dat similarity index 100% rename from RISP_data/time213.dat rename to data/RISP_data/time213.dat diff --git a/RISP_data/time214.dat b/data/RISP_data/time214.dat similarity index 100% rename from RISP_data/time214.dat rename to data/RISP_data/time214.dat diff --git a/RISP_data/time215.dat b/data/RISP_data/time215.dat similarity index 100% rename from RISP_data/time215.dat rename to data/RISP_data/time215.dat diff --git a/RISP_data/time216.dat b/data/RISP_data/time216.dat similarity index 100% rename from RISP_data/time216.dat rename to data/RISP_data/time216.dat diff --git a/RISP_data/time217.dat b/data/RISP_data/time217.dat similarity index 100% rename from RISP_data/time217.dat rename to data/RISP_data/time217.dat diff --git a/RISP_data/time218.dat b/data/RISP_data/time218.dat similarity index 100% rename from RISP_data/time218.dat rename to data/RISP_data/time218.dat diff --git a/RISP_data/time219.dat b/data/RISP_data/time219.dat similarity index 100% rename from RISP_data/time219.dat rename to data/RISP_data/time219.dat diff --git a/RISP_data/time220.dat b/data/RISP_data/time220.dat similarity index 100% rename from RISP_data/time220.dat rename to data/RISP_data/time220.dat diff --git a/RISP_data/time221.dat b/data/RISP_data/time221.dat similarity index 100% rename from RISP_data/time221.dat rename to data/RISP_data/time221.dat diff --git a/RISP_data/time222.dat b/data/RISP_data/time222.dat similarity index 100% rename from RISP_data/time222.dat rename to data/RISP_data/time222.dat diff --git a/RISP_data/time223.dat b/data/RISP_data/time223.dat similarity index 100% rename from RISP_data/time223.dat rename to data/RISP_data/time223.dat diff --git a/RISP_data/time224.dat b/data/RISP_data/time224.dat similarity index 100% rename from RISP_data/time224.dat rename to data/RISP_data/time224.dat diff --git a/RISP_data/time225.dat b/data/RISP_data/time225.dat similarity index 100% rename from RISP_data/time225.dat rename to data/RISP_data/time225.dat diff --git a/RISP_data/time226.dat b/data/RISP_data/time226.dat similarity index 100% rename from RISP_data/time226.dat rename to data/RISP_data/time226.dat diff --git a/RISP_data/time227.dat b/data/RISP_data/time227.dat similarity index 100% rename from RISP_data/time227.dat rename to data/RISP_data/time227.dat diff --git a/RISP_data/time228.dat b/data/RISP_data/time228.dat similarity index 100% rename from RISP_data/time228.dat rename to data/RISP_data/time228.dat diff --git a/RISP_data/time229.dat b/data/RISP_data/time229.dat similarity index 100% rename from RISP_data/time229.dat rename to data/RISP_data/time229.dat diff --git a/RISP_data/time230.dat b/data/RISP_data/time230.dat similarity index 100% rename from RISP_data/time230.dat rename to data/RISP_data/time230.dat diff --git a/RISP_data/time231.dat b/data/RISP_data/time231.dat similarity index 100% rename from RISP_data/time231.dat rename to data/RISP_data/time231.dat diff --git a/RISP_data/time232.dat b/data/RISP_data/time232.dat similarity index 100% rename from RISP_data/time232.dat rename to data/RISP_data/time232.dat diff --git a/RISP_data/time233.dat b/data/RISP_data/time233.dat similarity index 100% rename from RISP_data/time233.dat rename to data/RISP_data/time233.dat diff --git a/RISP_data/time234.dat b/data/RISP_data/time234.dat similarity index 100% rename from RISP_data/time234.dat rename to data/RISP_data/time234.dat diff --git a/RISP_data/time235.dat b/data/RISP_data/time235.dat similarity index 100% rename from RISP_data/time235.dat rename to data/RISP_data/time235.dat diff --git a/RISP_data/time236.dat b/data/RISP_data/time236.dat similarity index 100% rename from RISP_data/time236.dat rename to data/RISP_data/time236.dat diff --git a/RISP_data/time237.dat b/data/RISP_data/time237.dat similarity index 100% rename from RISP_data/time237.dat rename to data/RISP_data/time237.dat diff --git a/RISP_data/time238.dat b/data/RISP_data/time238.dat similarity index 100% rename from RISP_data/time238.dat rename to data/RISP_data/time238.dat diff --git a/RISP_data/time239.dat b/data/RISP_data/time239.dat similarity index 100% rename from RISP_data/time239.dat rename to data/RISP_data/time239.dat diff --git a/RISP_data/time240.dat b/data/RISP_data/time240.dat similarity index 100% rename from RISP_data/time240.dat rename to data/RISP_data/time240.dat diff --git a/RISP_data/time241.dat b/data/RISP_data/time241.dat similarity index 100% rename from RISP_data/time241.dat rename to data/RISP_data/time241.dat diff --git a/RISP_data/time242.dat b/data/RISP_data/time242.dat similarity index 100% rename from RISP_data/time242.dat rename to data/RISP_data/time242.dat diff --git a/RISP_data/time243.dat b/data/RISP_data/time243.dat similarity index 100% rename from RISP_data/time243.dat rename to data/RISP_data/time243.dat diff --git a/RISP_data/time244.dat b/data/RISP_data/time244.dat similarity index 100% rename from RISP_data/time244.dat rename to data/RISP_data/time244.dat diff --git a/RISP_data/time245.dat b/data/RISP_data/time245.dat similarity index 100% rename from RISP_data/time245.dat rename to data/RISP_data/time245.dat diff --git a/RISP_data/time246.dat b/data/RISP_data/time246.dat similarity index 100% rename from RISP_data/time246.dat rename to data/RISP_data/time246.dat diff --git a/RISP_data/time247.dat b/data/RISP_data/time247.dat similarity index 100% rename from RISP_data/time247.dat rename to data/RISP_data/time247.dat diff --git a/RISP_data/time248.dat b/data/RISP_data/time248.dat similarity index 100% rename from RISP_data/time248.dat rename to data/RISP_data/time248.dat diff --git a/RISP_data/time249.dat b/data/RISP_data/time249.dat similarity index 100% rename from RISP_data/time249.dat rename to data/RISP_data/time249.dat diff --git a/RISP_data/time250.dat b/data/RISP_data/time250.dat similarity index 100% rename from RISP_data/time250.dat rename to data/RISP_data/time250.dat diff --git a/RISP_data/time251.dat b/data/RISP_data/time251.dat similarity index 100% rename from RISP_data/time251.dat rename to data/RISP_data/time251.dat diff --git a/RISP_data/time252.dat b/data/RISP_data/time252.dat similarity index 100% rename from RISP_data/time252.dat rename to data/RISP_data/time252.dat diff --git a/RISP_data/time253.dat b/data/RISP_data/time253.dat similarity index 100% rename from RISP_data/time253.dat rename to data/RISP_data/time253.dat diff --git a/RISP_data/time254.dat b/data/RISP_data/time254.dat similarity index 100% rename from RISP_data/time254.dat rename to data/RISP_data/time254.dat diff --git a/RISP_data/time255.dat b/data/RISP_data/time255.dat similarity index 100% rename from RISP_data/time255.dat rename to data/RISP_data/time255.dat diff --git a/RISP_data/time256.dat b/data/RISP_data/time256.dat similarity index 100% rename from RISP_data/time256.dat rename to data/RISP_data/time256.dat diff --git a/RISP_data/time257.dat b/data/RISP_data/time257.dat similarity index 100% rename from RISP_data/time257.dat rename to data/RISP_data/time257.dat diff --git a/RISP_data/time258.dat b/data/RISP_data/time258.dat similarity index 100% rename from RISP_data/time258.dat rename to data/RISP_data/time258.dat diff --git a/RISP_data/time259.dat b/data/RISP_data/time259.dat similarity index 100% rename from RISP_data/time259.dat rename to data/RISP_data/time259.dat diff --git a/RISP_data/time260.dat b/data/RISP_data/time260.dat similarity index 100% rename from RISP_data/time260.dat rename to data/RISP_data/time260.dat diff --git a/RISP_data/time270.dat b/data/RISP_data/time270.dat similarity index 100% rename from RISP_data/time270.dat rename to data/RISP_data/time270.dat diff --git a/ROSP_data/.DS_Store b/data/ROSP_data/.DS_Store similarity index 100% rename from ROSP_data/.DS_Store rename to data/ROSP_data/.DS_Store diff --git a/ROSP_data/time0.dat b/data/ROSP_data/time0.dat similarity index 100% rename from ROSP_data/time0.dat rename to data/ROSP_data/time0.dat diff --git a/ROSP_data/time10.dat b/data/ROSP_data/time10.dat similarity index 100% rename from ROSP_data/time10.dat rename to data/ROSP_data/time10.dat diff --git a/ROSP_data/time100.dat b/data/ROSP_data/time100.dat similarity index 100% rename from ROSP_data/time100.dat rename to data/ROSP_data/time100.dat diff --git a/ROSP_data/time101.dat b/data/ROSP_data/time101.dat similarity index 100% rename from ROSP_data/time101.dat rename to data/ROSP_data/time101.dat diff --git a/ROSP_data/time102.dat b/data/ROSP_data/time102.dat similarity index 100% rename from ROSP_data/time102.dat rename to data/ROSP_data/time102.dat diff --git a/ROSP_data/time103.dat b/data/ROSP_data/time103.dat similarity index 100% rename from ROSP_data/time103.dat rename to data/ROSP_data/time103.dat diff --git a/ROSP_data/time104.dat b/data/ROSP_data/time104.dat similarity index 100% rename from ROSP_data/time104.dat rename to data/ROSP_data/time104.dat diff --git a/ROSP_data/time105.dat b/data/ROSP_data/time105.dat similarity index 100% rename from ROSP_data/time105.dat rename to data/ROSP_data/time105.dat diff --git a/ROSP_data/time106.dat b/data/ROSP_data/time106.dat similarity index 100% rename from ROSP_data/time106.dat rename to data/ROSP_data/time106.dat diff --git a/ROSP_data/time107.dat b/data/ROSP_data/time107.dat similarity index 100% rename from ROSP_data/time107.dat rename to data/ROSP_data/time107.dat diff --git a/ROSP_data/time108.dat b/data/ROSP_data/time108.dat similarity index 100% rename from ROSP_data/time108.dat rename to data/ROSP_data/time108.dat diff --git a/ROSP_data/time109.dat b/data/ROSP_data/time109.dat similarity index 100% rename from ROSP_data/time109.dat rename to data/ROSP_data/time109.dat diff --git a/ROSP_data/time110.dat b/data/ROSP_data/time110.dat similarity index 100% rename from ROSP_data/time110.dat rename to data/ROSP_data/time110.dat diff --git a/ROSP_data/time111.dat b/data/ROSP_data/time111.dat similarity index 100% rename from ROSP_data/time111.dat rename to data/ROSP_data/time111.dat diff --git a/ROSP_data/time112.dat b/data/ROSP_data/time112.dat similarity index 100% rename from ROSP_data/time112.dat rename to data/ROSP_data/time112.dat diff --git a/ROSP_data/time113.dat b/data/ROSP_data/time113.dat similarity index 100% rename from ROSP_data/time113.dat rename to data/ROSP_data/time113.dat diff --git a/ROSP_data/time114.dat b/data/ROSP_data/time114.dat similarity index 100% rename from ROSP_data/time114.dat rename to data/ROSP_data/time114.dat diff --git a/ROSP_data/time115.dat b/data/ROSP_data/time115.dat similarity index 100% rename from ROSP_data/time115.dat rename to data/ROSP_data/time115.dat diff --git a/ROSP_data/time116.dat b/data/ROSP_data/time116.dat similarity index 100% rename from ROSP_data/time116.dat rename to data/ROSP_data/time116.dat diff --git a/ROSP_data/time117.dat b/data/ROSP_data/time117.dat similarity index 100% rename from ROSP_data/time117.dat rename to data/ROSP_data/time117.dat diff --git a/ROSP_data/time118.dat b/data/ROSP_data/time118.dat similarity index 100% rename from ROSP_data/time118.dat rename to data/ROSP_data/time118.dat diff --git a/ROSP_data/time119.dat b/data/ROSP_data/time119.dat similarity index 100% rename from ROSP_data/time119.dat rename to data/ROSP_data/time119.dat diff --git a/ROSP_data/time120.dat b/data/ROSP_data/time120.dat similarity index 100% rename from ROSP_data/time120.dat rename to data/ROSP_data/time120.dat diff --git a/ROSP_data/time121.dat b/data/ROSP_data/time121.dat similarity index 100% rename from ROSP_data/time121.dat rename to data/ROSP_data/time121.dat diff --git a/ROSP_data/time122.dat b/data/ROSP_data/time122.dat similarity index 100% rename from ROSP_data/time122.dat rename to data/ROSP_data/time122.dat diff --git a/ROSP_data/time123.dat b/data/ROSP_data/time123.dat similarity index 100% rename from ROSP_data/time123.dat rename to data/ROSP_data/time123.dat diff --git a/ROSP_data/time124.dat b/data/ROSP_data/time124.dat similarity index 100% rename from ROSP_data/time124.dat rename to data/ROSP_data/time124.dat diff --git a/ROSP_data/time125.dat b/data/ROSP_data/time125.dat similarity index 100% rename from ROSP_data/time125.dat rename to data/ROSP_data/time125.dat diff --git a/ROSP_data/time126.dat b/data/ROSP_data/time126.dat similarity index 100% rename from ROSP_data/time126.dat rename to data/ROSP_data/time126.dat diff --git a/ROSP_data/time127.dat b/data/ROSP_data/time127.dat similarity index 100% rename from ROSP_data/time127.dat rename to data/ROSP_data/time127.dat diff --git a/ROSP_data/time128.dat b/data/ROSP_data/time128.dat similarity index 100% rename from ROSP_data/time128.dat rename to data/ROSP_data/time128.dat diff --git a/ROSP_data/time129.dat b/data/ROSP_data/time129.dat similarity index 100% rename from ROSP_data/time129.dat rename to data/ROSP_data/time129.dat diff --git a/ROSP_data/time130.dat b/data/ROSP_data/time130.dat similarity index 100% rename from ROSP_data/time130.dat rename to data/ROSP_data/time130.dat diff --git a/ROSP_data/time131.dat b/data/ROSP_data/time131.dat similarity index 100% rename from ROSP_data/time131.dat rename to data/ROSP_data/time131.dat diff --git a/ROSP_data/time132.dat b/data/ROSP_data/time132.dat similarity index 100% rename from ROSP_data/time132.dat rename to data/ROSP_data/time132.dat diff --git a/ROSP_data/time133.dat b/data/ROSP_data/time133.dat similarity index 100% rename from ROSP_data/time133.dat rename to data/ROSP_data/time133.dat diff --git a/ROSP_data/time134.dat b/data/ROSP_data/time134.dat similarity index 100% rename from ROSP_data/time134.dat rename to data/ROSP_data/time134.dat diff --git a/ROSP_data/time135.dat b/data/ROSP_data/time135.dat similarity index 100% rename from ROSP_data/time135.dat rename to data/ROSP_data/time135.dat diff --git a/ROSP_data/time136.dat b/data/ROSP_data/time136.dat similarity index 100% rename from ROSP_data/time136.dat rename to data/ROSP_data/time136.dat diff --git a/ROSP_data/time137.dat b/data/ROSP_data/time137.dat similarity index 100% rename from ROSP_data/time137.dat rename to data/ROSP_data/time137.dat diff --git a/ROSP_data/time138.dat b/data/ROSP_data/time138.dat similarity index 100% rename from ROSP_data/time138.dat rename to data/ROSP_data/time138.dat diff --git a/ROSP_data/time139.dat b/data/ROSP_data/time139.dat similarity index 100% rename from ROSP_data/time139.dat rename to data/ROSP_data/time139.dat diff --git a/ROSP_data/time140.dat b/data/ROSP_data/time140.dat similarity index 100% rename from ROSP_data/time140.dat rename to data/ROSP_data/time140.dat diff --git a/ROSP_data/time141.dat b/data/ROSP_data/time141.dat similarity index 100% rename from ROSP_data/time141.dat rename to data/ROSP_data/time141.dat diff --git a/ROSP_data/time142.dat b/data/ROSP_data/time142.dat similarity index 100% rename from ROSP_data/time142.dat rename to data/ROSP_data/time142.dat diff --git a/ROSP_data/time143.dat b/data/ROSP_data/time143.dat similarity index 100% rename from ROSP_data/time143.dat rename to data/ROSP_data/time143.dat diff --git a/ROSP_data/time144.dat b/data/ROSP_data/time144.dat similarity index 100% rename from ROSP_data/time144.dat rename to data/ROSP_data/time144.dat diff --git a/ROSP_data/time145.dat b/data/ROSP_data/time145.dat similarity index 100% rename from ROSP_data/time145.dat rename to data/ROSP_data/time145.dat diff --git a/ROSP_data/time146.dat b/data/ROSP_data/time146.dat similarity index 100% rename from ROSP_data/time146.dat rename to data/ROSP_data/time146.dat diff --git a/ROSP_data/time147.dat b/data/ROSP_data/time147.dat similarity index 100% rename from ROSP_data/time147.dat rename to data/ROSP_data/time147.dat diff --git a/ROSP_data/time148.dat b/data/ROSP_data/time148.dat similarity index 100% rename from ROSP_data/time148.dat rename to data/ROSP_data/time148.dat diff --git a/ROSP_data/time149.dat b/data/ROSP_data/time149.dat similarity index 100% rename from ROSP_data/time149.dat rename to data/ROSP_data/time149.dat diff --git a/ROSP_data/time150.dat b/data/ROSP_data/time150.dat similarity index 100% rename from ROSP_data/time150.dat rename to data/ROSP_data/time150.dat diff --git a/ROSP_data/time151.dat b/data/ROSP_data/time151.dat similarity index 100% rename from ROSP_data/time151.dat rename to data/ROSP_data/time151.dat diff --git a/ROSP_data/time152.dat b/data/ROSP_data/time152.dat similarity index 100% rename from ROSP_data/time152.dat rename to data/ROSP_data/time152.dat diff --git a/ROSP_data/time153.dat b/data/ROSP_data/time153.dat similarity index 100% rename from ROSP_data/time153.dat rename to data/ROSP_data/time153.dat diff --git a/ROSP_data/time154.dat b/data/ROSP_data/time154.dat similarity index 100% rename from ROSP_data/time154.dat rename to data/ROSP_data/time154.dat diff --git a/ROSP_data/time155.dat b/data/ROSP_data/time155.dat similarity index 100% rename from ROSP_data/time155.dat rename to data/ROSP_data/time155.dat diff --git a/ROSP_data/time156.dat b/data/ROSP_data/time156.dat similarity index 100% rename from ROSP_data/time156.dat rename to data/ROSP_data/time156.dat diff --git a/ROSP_data/time157.dat b/data/ROSP_data/time157.dat similarity index 100% rename from ROSP_data/time157.dat rename to data/ROSP_data/time157.dat diff --git a/ROSP_data/time158.dat b/data/ROSP_data/time158.dat similarity index 100% rename from ROSP_data/time158.dat rename to data/ROSP_data/time158.dat diff --git a/ROSP_data/time159.dat b/data/ROSP_data/time159.dat similarity index 100% rename from ROSP_data/time159.dat rename to data/ROSP_data/time159.dat diff --git a/ROSP_data/time160.dat b/data/ROSP_data/time160.dat similarity index 100% rename from ROSP_data/time160.dat rename to data/ROSP_data/time160.dat diff --git a/ROSP_data/time161.dat b/data/ROSP_data/time161.dat similarity index 100% rename from ROSP_data/time161.dat rename to data/ROSP_data/time161.dat diff --git a/ROSP_data/time162.dat b/data/ROSP_data/time162.dat similarity index 100% rename from ROSP_data/time162.dat rename to data/ROSP_data/time162.dat diff --git a/ROSP_data/time163.dat b/data/ROSP_data/time163.dat similarity index 100% rename from ROSP_data/time163.dat rename to data/ROSP_data/time163.dat diff --git a/ROSP_data/time164.dat b/data/ROSP_data/time164.dat similarity index 100% rename from ROSP_data/time164.dat rename to data/ROSP_data/time164.dat diff --git a/ROSP_data/time165.dat b/data/ROSP_data/time165.dat similarity index 100% rename from ROSP_data/time165.dat rename to data/ROSP_data/time165.dat diff --git a/ROSP_data/time166.dat b/data/ROSP_data/time166.dat similarity index 100% rename from ROSP_data/time166.dat rename to data/ROSP_data/time166.dat diff --git a/ROSP_data/time167.dat b/data/ROSP_data/time167.dat similarity index 100% rename from ROSP_data/time167.dat rename to data/ROSP_data/time167.dat diff --git a/ROSP_data/time168.dat b/data/ROSP_data/time168.dat similarity index 100% rename from ROSP_data/time168.dat rename to data/ROSP_data/time168.dat diff --git a/ROSP_data/time169.dat b/data/ROSP_data/time169.dat similarity index 100% rename from ROSP_data/time169.dat rename to data/ROSP_data/time169.dat diff --git a/ROSP_data/time170.dat b/data/ROSP_data/time170.dat similarity index 100% rename from ROSP_data/time170.dat rename to data/ROSP_data/time170.dat diff --git a/ROSP_data/time171.dat b/data/ROSP_data/time171.dat similarity index 100% rename from ROSP_data/time171.dat rename to data/ROSP_data/time171.dat diff --git a/ROSP_data/time172.dat b/data/ROSP_data/time172.dat similarity index 100% rename from ROSP_data/time172.dat rename to data/ROSP_data/time172.dat diff --git a/ROSP_data/time173.dat b/data/ROSP_data/time173.dat similarity index 100% rename from ROSP_data/time173.dat rename to data/ROSP_data/time173.dat diff --git a/ROSP_data/time174.dat b/data/ROSP_data/time174.dat similarity index 100% rename from ROSP_data/time174.dat rename to data/ROSP_data/time174.dat diff --git a/ROSP_data/time175.dat b/data/ROSP_data/time175.dat similarity index 100% rename from ROSP_data/time175.dat rename to data/ROSP_data/time175.dat diff --git a/ROSP_data/time176.dat b/data/ROSP_data/time176.dat similarity index 100% rename from ROSP_data/time176.dat rename to data/ROSP_data/time176.dat diff --git a/ROSP_data/time177.dat b/data/ROSP_data/time177.dat similarity index 100% rename from ROSP_data/time177.dat rename to data/ROSP_data/time177.dat diff --git a/ROSP_data/time178.dat b/data/ROSP_data/time178.dat similarity index 100% rename from ROSP_data/time178.dat rename to data/ROSP_data/time178.dat diff --git a/ROSP_data/time179.dat b/data/ROSP_data/time179.dat similarity index 100% rename from ROSP_data/time179.dat rename to data/ROSP_data/time179.dat diff --git a/ROSP_data/time180.dat b/data/ROSP_data/time180.dat similarity index 100% rename from ROSP_data/time180.dat rename to data/ROSP_data/time180.dat diff --git a/ROSP_data/time181.dat b/data/ROSP_data/time181.dat similarity index 100% rename from ROSP_data/time181.dat rename to data/ROSP_data/time181.dat diff --git a/ROSP_data/time182.dat b/data/ROSP_data/time182.dat similarity index 100% rename from ROSP_data/time182.dat rename to data/ROSP_data/time182.dat diff --git a/ROSP_data/time183.dat b/data/ROSP_data/time183.dat similarity index 100% rename from ROSP_data/time183.dat rename to data/ROSP_data/time183.dat diff --git a/ROSP_data/time184.dat b/data/ROSP_data/time184.dat similarity index 100% rename from ROSP_data/time184.dat rename to data/ROSP_data/time184.dat diff --git a/ROSP_data/time185.dat b/data/ROSP_data/time185.dat similarity index 100% rename from ROSP_data/time185.dat rename to data/ROSP_data/time185.dat diff --git a/ROSP_data/time186.dat b/data/ROSP_data/time186.dat similarity index 100% rename from ROSP_data/time186.dat rename to data/ROSP_data/time186.dat diff --git a/ROSP_data/time187.dat b/data/ROSP_data/time187.dat similarity index 100% rename from ROSP_data/time187.dat rename to data/ROSP_data/time187.dat diff --git a/ROSP_data/time188.dat b/data/ROSP_data/time188.dat similarity index 100% rename from ROSP_data/time188.dat rename to data/ROSP_data/time188.dat diff --git a/ROSP_data/time189.dat b/data/ROSP_data/time189.dat similarity index 100% rename from ROSP_data/time189.dat rename to data/ROSP_data/time189.dat diff --git a/ROSP_data/time190.dat b/data/ROSP_data/time190.dat similarity index 100% rename from ROSP_data/time190.dat rename to data/ROSP_data/time190.dat diff --git a/ROSP_data/time191.dat b/data/ROSP_data/time191.dat similarity index 100% rename from ROSP_data/time191.dat rename to data/ROSP_data/time191.dat diff --git a/ROSP_data/time192.dat b/data/ROSP_data/time192.dat similarity index 100% rename from ROSP_data/time192.dat rename to data/ROSP_data/time192.dat diff --git a/ROSP_data/time193.dat b/data/ROSP_data/time193.dat similarity index 100% rename from ROSP_data/time193.dat rename to data/ROSP_data/time193.dat diff --git a/ROSP_data/time194.dat b/data/ROSP_data/time194.dat similarity index 100% rename from ROSP_data/time194.dat rename to data/ROSP_data/time194.dat diff --git a/ROSP_data/time195.dat b/data/ROSP_data/time195.dat similarity index 100% rename from ROSP_data/time195.dat rename to data/ROSP_data/time195.dat diff --git a/ROSP_data/time196.dat b/data/ROSP_data/time196.dat similarity index 100% rename from ROSP_data/time196.dat rename to data/ROSP_data/time196.dat diff --git a/ROSP_data/time197.dat b/data/ROSP_data/time197.dat similarity index 100% rename from ROSP_data/time197.dat rename to data/ROSP_data/time197.dat diff --git a/ROSP_data/time198.dat b/data/ROSP_data/time198.dat similarity index 100% rename from ROSP_data/time198.dat rename to data/ROSP_data/time198.dat diff --git a/ROSP_data/time199.dat b/data/ROSP_data/time199.dat similarity index 100% rename from ROSP_data/time199.dat rename to data/ROSP_data/time199.dat diff --git a/ROSP_data/time200.dat b/data/ROSP_data/time200.dat similarity index 100% rename from ROSP_data/time200.dat rename to data/ROSP_data/time200.dat diff --git a/ROSP_data/time201.dat b/data/ROSP_data/time201.dat similarity index 100% rename from ROSP_data/time201.dat rename to data/ROSP_data/time201.dat diff --git a/ROSP_data/time202.dat b/data/ROSP_data/time202.dat similarity index 100% rename from ROSP_data/time202.dat rename to data/ROSP_data/time202.dat diff --git a/ROSP_data/time203.dat b/data/ROSP_data/time203.dat similarity index 100% rename from ROSP_data/time203.dat rename to data/ROSP_data/time203.dat diff --git a/ROSP_data/time204.dat b/data/ROSP_data/time204.dat similarity index 100% rename from ROSP_data/time204.dat rename to data/ROSP_data/time204.dat diff --git a/ROSP_data/time205.dat b/data/ROSP_data/time205.dat similarity index 100% rename from ROSP_data/time205.dat rename to data/ROSP_data/time205.dat diff --git a/ROSP_data/time206.dat b/data/ROSP_data/time206.dat similarity index 100% rename from ROSP_data/time206.dat rename to data/ROSP_data/time206.dat diff --git a/ROSP_data/time207.dat b/data/ROSP_data/time207.dat similarity index 100% rename from ROSP_data/time207.dat rename to data/ROSP_data/time207.dat diff --git a/ROSP_data/time208.dat b/data/ROSP_data/time208.dat similarity index 100% rename from ROSP_data/time208.dat rename to data/ROSP_data/time208.dat diff --git a/ROSP_data/time209.dat b/data/ROSP_data/time209.dat similarity index 100% rename from ROSP_data/time209.dat rename to data/ROSP_data/time209.dat diff --git a/ROSP_data/time210.dat b/data/ROSP_data/time210.dat similarity index 100% rename from ROSP_data/time210.dat rename to data/ROSP_data/time210.dat diff --git a/ROSP_data/time211.dat b/data/ROSP_data/time211.dat similarity index 100% rename from ROSP_data/time211.dat rename to data/ROSP_data/time211.dat diff --git a/ROSP_data/time212.dat b/data/ROSP_data/time212.dat similarity index 100% rename from ROSP_data/time212.dat rename to data/ROSP_data/time212.dat diff --git a/ROSP_data/time213.dat b/data/ROSP_data/time213.dat similarity index 100% rename from ROSP_data/time213.dat rename to data/ROSP_data/time213.dat diff --git a/ROSP_data/time214.dat b/data/ROSP_data/time214.dat similarity index 100% rename from ROSP_data/time214.dat rename to data/ROSP_data/time214.dat diff --git a/ROSP_data/time215.dat b/data/ROSP_data/time215.dat similarity index 100% rename from ROSP_data/time215.dat rename to data/ROSP_data/time215.dat diff --git a/ROSP_data/time216.dat b/data/ROSP_data/time216.dat similarity index 100% rename from ROSP_data/time216.dat rename to data/ROSP_data/time216.dat diff --git a/ROSP_data/time217.dat b/data/ROSP_data/time217.dat similarity index 100% rename from ROSP_data/time217.dat rename to data/ROSP_data/time217.dat diff --git a/ROSP_data/time218.dat b/data/ROSP_data/time218.dat similarity index 100% rename from ROSP_data/time218.dat rename to data/ROSP_data/time218.dat diff --git a/ROSP_data/time219.dat b/data/ROSP_data/time219.dat similarity index 100% rename from ROSP_data/time219.dat rename to data/ROSP_data/time219.dat diff --git a/ROSP_data/time220.dat b/data/ROSP_data/time220.dat similarity index 100% rename from ROSP_data/time220.dat rename to data/ROSP_data/time220.dat diff --git a/ROSP_data/time221.dat b/data/ROSP_data/time221.dat similarity index 100% rename from ROSP_data/time221.dat rename to data/ROSP_data/time221.dat diff --git a/ROSP_data/time222.dat b/data/ROSP_data/time222.dat similarity index 100% rename from ROSP_data/time222.dat rename to data/ROSP_data/time222.dat diff --git a/ROSP_data/time223.dat b/data/ROSP_data/time223.dat similarity index 100% rename from ROSP_data/time223.dat rename to data/ROSP_data/time223.dat diff --git a/ROSP_data/time224.dat b/data/ROSP_data/time224.dat similarity index 100% rename from ROSP_data/time224.dat rename to data/ROSP_data/time224.dat diff --git a/ROSP_data/time225.dat b/data/ROSP_data/time225.dat similarity index 100% rename from ROSP_data/time225.dat rename to data/ROSP_data/time225.dat diff --git a/ROSP_data/time226.dat b/data/ROSP_data/time226.dat similarity index 100% rename from ROSP_data/time226.dat rename to data/ROSP_data/time226.dat diff --git a/ROSP_data/time227.dat b/data/ROSP_data/time227.dat similarity index 100% rename from ROSP_data/time227.dat rename to data/ROSP_data/time227.dat diff --git a/ROSP_data/time228.dat b/data/ROSP_data/time228.dat similarity index 100% rename from ROSP_data/time228.dat rename to data/ROSP_data/time228.dat diff --git a/ROSP_data/time229.dat b/data/ROSP_data/time229.dat similarity index 100% rename from ROSP_data/time229.dat rename to data/ROSP_data/time229.dat diff --git a/ROSP_data/time230.dat b/data/ROSP_data/time230.dat similarity index 100% rename from ROSP_data/time230.dat rename to data/ROSP_data/time230.dat diff --git a/ROSP_data/time231.dat b/data/ROSP_data/time231.dat similarity index 100% rename from ROSP_data/time231.dat rename to data/ROSP_data/time231.dat diff --git a/ROSP_data/time232.dat b/data/ROSP_data/time232.dat similarity index 100% rename from ROSP_data/time232.dat rename to data/ROSP_data/time232.dat diff --git a/ROSP_data/time233.dat b/data/ROSP_data/time233.dat similarity index 100% rename from ROSP_data/time233.dat rename to data/ROSP_data/time233.dat diff --git a/ROSP_data/time234.dat b/data/ROSP_data/time234.dat similarity index 100% rename from ROSP_data/time234.dat rename to data/ROSP_data/time234.dat diff --git a/ROSP_data/time235.dat b/data/ROSP_data/time235.dat similarity index 100% rename from ROSP_data/time235.dat rename to data/ROSP_data/time235.dat diff --git a/ROSP_data/time236.dat b/data/ROSP_data/time236.dat similarity index 100% rename from ROSP_data/time236.dat rename to data/ROSP_data/time236.dat diff --git a/ROSP_data/time237.dat b/data/ROSP_data/time237.dat similarity index 100% rename from ROSP_data/time237.dat rename to data/ROSP_data/time237.dat diff --git a/ROSP_data/time238.dat b/data/ROSP_data/time238.dat similarity index 100% rename from ROSP_data/time238.dat rename to data/ROSP_data/time238.dat diff --git a/ROSP_data/time239.dat b/data/ROSP_data/time239.dat similarity index 100% rename from ROSP_data/time239.dat rename to data/ROSP_data/time239.dat diff --git a/ROSP_data/time240.dat b/data/ROSP_data/time240.dat similarity index 100% rename from ROSP_data/time240.dat rename to data/ROSP_data/time240.dat diff --git a/ROSP_data/time241.dat b/data/ROSP_data/time241.dat similarity index 100% rename from ROSP_data/time241.dat rename to data/ROSP_data/time241.dat diff --git a/ROSP_data/time242.dat b/data/ROSP_data/time242.dat similarity index 100% rename from ROSP_data/time242.dat rename to data/ROSP_data/time242.dat diff --git a/ROSP_data/time243.dat b/data/ROSP_data/time243.dat similarity index 100% rename from ROSP_data/time243.dat rename to data/ROSP_data/time243.dat diff --git a/ROSP_data/time244.dat b/data/ROSP_data/time244.dat similarity index 100% rename from ROSP_data/time244.dat rename to data/ROSP_data/time244.dat diff --git a/ROSP_data/time245.dat b/data/ROSP_data/time245.dat similarity index 100% rename from ROSP_data/time245.dat rename to data/ROSP_data/time245.dat diff --git a/ROSP_data/time246.dat b/data/ROSP_data/time246.dat similarity index 100% rename from ROSP_data/time246.dat rename to data/ROSP_data/time246.dat diff --git a/ROSP_data/time247.dat b/data/ROSP_data/time247.dat similarity index 100% rename from ROSP_data/time247.dat rename to data/ROSP_data/time247.dat diff --git a/ROSP_data/time248.dat b/data/ROSP_data/time248.dat similarity index 100% rename from ROSP_data/time248.dat rename to data/ROSP_data/time248.dat diff --git a/ROSP_data/time249.dat b/data/ROSP_data/time249.dat similarity index 100% rename from ROSP_data/time249.dat rename to data/ROSP_data/time249.dat diff --git a/ROSP_data/time250.dat b/data/ROSP_data/time250.dat similarity index 100% rename from ROSP_data/time250.dat rename to data/ROSP_data/time250.dat diff --git a/ROSP_data/time251.dat b/data/ROSP_data/time251.dat similarity index 100% rename from ROSP_data/time251.dat rename to data/ROSP_data/time251.dat diff --git a/ROSP_data/time252.dat b/data/ROSP_data/time252.dat similarity index 100% rename from ROSP_data/time252.dat rename to data/ROSP_data/time252.dat diff --git a/ROSP_data/time253.dat b/data/ROSP_data/time253.dat similarity index 100% rename from ROSP_data/time253.dat rename to data/ROSP_data/time253.dat diff --git a/ROSP_data/time254.dat b/data/ROSP_data/time254.dat similarity index 100% rename from ROSP_data/time254.dat rename to data/ROSP_data/time254.dat diff --git a/ROSP_data/time255.dat b/data/ROSP_data/time255.dat similarity index 100% rename from ROSP_data/time255.dat rename to data/ROSP_data/time255.dat diff --git a/ROSP_data/time256.dat b/data/ROSP_data/time256.dat similarity index 100% rename from ROSP_data/time256.dat rename to data/ROSP_data/time256.dat diff --git a/ROSP_data/time257.dat b/data/ROSP_data/time257.dat similarity index 100% rename from ROSP_data/time257.dat rename to data/ROSP_data/time257.dat diff --git a/ROSP_data/time258.dat b/data/ROSP_data/time258.dat similarity index 100% rename from ROSP_data/time258.dat rename to data/ROSP_data/time258.dat diff --git a/ROSP_data/time259.dat b/data/ROSP_data/time259.dat similarity index 100% rename from ROSP_data/time259.dat rename to data/ROSP_data/time259.dat diff --git a/ROSP_data/time260.dat b/data/ROSP_data/time260.dat similarity index 100% rename from ROSP_data/time260.dat rename to data/ROSP_data/time260.dat diff --git a/ROSP_data/time270.dat b/data/ROSP_data/time270.dat similarity index 100% rename from ROSP_data/time270.dat rename to data/ROSP_data/time270.dat diff --git a/environment.yml b/environment.yml index 741eaa1..892b004 100644 --- a/environment.yml +++ b/environment.yml @@ -6,6 +6,7 @@ dependencies: - fenics-dolfinx=0.9.0 - matplotlib - scipy + - pandas - pint # need to install pint with conda to avoid conflicts (HTM) - pip - pip: diff --git a/mb_scenario.py b/mb_scenario.py index f664963..e2da90a 100644 --- a/mb_scenario.py +++ b/mb_scenario.py @@ -1,28 +1,18 @@ -# simple monoblock simulation in festim -import festim as F import numpy as np import matplotlib.pyplot as plt -import h_transport_materials as htm -import ufl -from dolfinx.fem.function import Constant -from scipy import constants -import dolfinx.fem as fem -import dolfinx +from numpy.typing import NDArray -from hisp.helpers import PulsedSource, Scenario -from hisp import CustomProblem +from hisp.plamsa_data_handling import PlasmaDataHandling +from hisp.festim_models import make_mb_model +from hisp.scenario import Scenario, Pulse +from hisp.helpers import periodic_step_function # dolfinx.log.set_log_level(dolfinx.log.LogLevel.INFO) NB_FP_PULSES_PER_DAY = 13 COOLANT_TEMP = 343 # 70 degree C cooling water -############# CUSTOM CLASSES FOR PULSED FLUXES & RECOMBO BC ############# - -# TODO: ADJUST TO HANDLE ANY STRAIGHT W 6MM SIMU -mb = 64 - # tritium fraction = T/D PULSE_TYPE_TO_TRITIUM_FRACTION = { "FP": 0.5, @@ -32,264 +22,51 @@ "BAKE": 0, } - -def gaussian_distribution(x, mod=ufl): - depth = 3e-9 - width = 1e-9 - return mod.exp(-((x[0] - depth) ** 2) / (2 * width**2)) - - -def make_mb_model(nb_mb, scenario_file): - ############# Input Flux, Heat Data ############# - my_scenario = Scenario(scenario_file) - - my_model = CustomProblem() - - ############# Material Parameters ############# - - L = 6e-3 # m - vertices = np.concatenate( # 1D mesh with extra refinement - [ - np.linspace(0, 30e-9, num=200), - np.linspace(30e-9, 3e-6, num=300), - np.linspace(3e-6, 30e-6, num=200), - np.linspace(30e-6, L, num=200), - ] - ) - my_model.mesh = F.Mesh1D(vertices) - - # W material parameters - w_density = 6.3382e28 # atoms/m3 - w_diffusivity = ( - htm.diffusivities.filter(material="tungsten") - .filter(isotope="h") - .filter(author="frauenfelder") - ) - w_diffusivity = w_diffusivity[0] - D_0 = w_diffusivity.pre_exp.magnitude - E_D = w_diffusivity.act_energy.magnitude - tungsten = F.Material( - D_0=D_0, - E_D=E_D, - name="tungsten", +if __name__ == "__main__": + # my_scenario = Scenario.from_txt_file("scenario_test.txt", old_format=True) + fp = Pulse( + pulse_type="FP", + nb_pulses=1, + ramp_up=10, + steady_state=10, + ramp_down=10, + waiting=100, ) - - # mb subdomains - w_subdomain = F.VolumeSubdomain1D(id=1, borders=[0, L], material=tungsten) - inlet = F.SurfaceSubdomain1D(id=1, x=0) - outlet = F.SurfaceSubdomain1D(id=2, x=L) - - my_model.subdomains = [ - w_subdomain, - inlet, - outlet, - ] - - # hydrogen species - mobile_D = F.Species("D") - mobile_T = F.Species("T") - - trap1_D = F.Species("trap1_D", mobile=False) - trap1_T = F.Species("trap1_T", mobile=False) - trap2_D = F.Species("trap2_D", mobile=False) - trap2_T = F.Species("trap2_T", mobile=False) - trap3_D = F.Species("trap3_D", mobile=False) - trap3_T = F.Species("trap3_T", mobile=False) - - # traps - empty_trap1 = F.ImplicitSpecies( # implicit trap 1 - n=6.338e24, # 1e-4 at.fr. - others=[trap1_T, trap1_D], - name="empty_trap1", + icwc = Pulse( + pulse_type="ICWC", + nb_pulses=1, + ramp_up=10, + steady_state=10, + ramp_down=10, + waiting=100, ) - - empty_trap2 = F.ImplicitSpecies( # implicit trap 2 - n=6.338e24, - others=[trap2_T, trap2_D], - name="empty_trap2", + risp = Pulse( + pulse_type="RISP", + nb_pulses=1, + ramp_up=10, + steady_state=10, + ramp_down=10, + waiting=100, ) - - # density_func = - empty_trap3 = F.ImplicitSpecies( # not implicit, but can simplify trap creation model to small damanged zone in first 10nm - n=6.338e27, # 1e-1 at.fr. - others=[trap3_T, trap3_D], - name="empty_trap3", + my_scenario = Scenario(pulses=[fp, icwc, risp]) + + data_folder = "data" + plasma_data_handling = PlasmaDataHandling( + pulse_type_to_data={ + "FP": np.loadtxt(data_folder + "/Binned_Flux_Data.dat", skiprows=1), + "ICWC": np.loadtxt(data_folder + "/ICWC_data.dat", skiprows=1), + "GDC": np.loadtxt(data_folder + "/GDC_data.dat", skiprows=1), + }, + path_to_ROSP_data=data_folder + "/ROSP_data", + path_to_RISP_data=data_folder + "/RISP_data", + path_to_RISP_wall_data=data_folder + "/RISP_Wall_data.dat", ) - my_model.species = [ - mobile_D, - mobile_T, - trap1_D, - trap1_T, - trap2_D, - trap2_T, - trap3_D, - trap3_T, - ] - - # hydrogen reactions - 1 per trap per species - my_model.reactions = [ - F.Reaction( - k_0=D_0 / (1.1e-10**2 * 6 * w_density), - E_k=E_D, - p_0=1e13, - E_p=0.85, - volume=w_subdomain, - reactant=[mobile_D, empty_trap1], - product=trap1_D, - ), - F.Reaction( - k_0=D_0 / (1.1e-10**2 * 6 * w_density), - E_k=E_D, - p_0=1e13, - E_p=0.85, - volume=w_subdomain, - reactant=[mobile_T, empty_trap1], - product=trap1_T, - ), - F.Reaction( - k_0=D_0 / (1.1e-10**2 * 6 * w_density), - E_k=E_D, - p_0=1e13, - E_p=1, - volume=w_subdomain, - reactant=[mobile_D, empty_trap2], - product=trap2_D, - ), - F.Reaction( - k_0=D_0 / (1.1e-10**2 * 6 * w_density), - E_k=E_D, - p_0=1e13, - E_p=1, - volume=w_subdomain, - reactant=[mobile_T, empty_trap2], - product=trap2_T, - ), - F.Reaction( - k_0=D_0 / (1.1e-10**2 * 6 * w_density), - E_k=E_D, - p_0=1e13, - E_p=1.5, - volume=w_subdomain, - reactant=[mobile_D, empty_trap3], - product=trap3_D, - ), - F.Reaction( - k_0=D_0 / (1.1e-10**2 * 6 * w_density), - E_k=E_D, - p_0=1e13, - E_p=1.5, - volume=w_subdomain, - reactant=[mobile_T, empty_trap3], - product=trap3_T, - ), - ] - - ############# Pulse Parameters (s) ############# - - # TODO change the dat file for other pulse types - pulse_type_to_DINA_data = { - "FP": np.loadtxt("Binned_Flux_Data.dat", skiprows=1), - "ICWC": np.loadtxt("ICWC_data.dat", skiprows=1), - "GDC": np.loadtxt("GDC_data.dat", skiprows=1), - } - - def RISP_data(monob, time): - """Returns the correct RISP data file for indicated monoblock - - Args: - monob (int): mb number - t (int): time as an integer - - Returns: - data (np.array): data from correct file as a numpy array - """ - inner_swept_bins = list(range(46,65)) - outer_swept_bins = list(range(19,34)) - - if monob in inner_swept_bins: - label = "RISP" - div = True - offset_mb = 46 - elif monob in outer_swept_bins: - label = "ROSP" - div = True - offset_mb = 19 - else: - div = False - offset_mb = 0 - - t = int(time) - - if div: - if t in list(range(1,10)): data = np.loadtxt(label+"_data/time0.dat", skiprows=1) - elif t in list(range(11,99)): data = np.loadtxt(label+"_data/time10.dat", skiprows=1) - elif t in list(range(100,261)): data = np.loadtxt(label+"_data/time"+str(t)+".dat", skiprows=1) - elif t in list(range(261,270)): data = np.loadtxt(label+"_data/time270.dat", skiprows=1) - else: data = np.loadtxt("RISP_Wall_data.dat", skiprows=1) - else: - data = np.loadtxt("RISP_Wall_data.dat", skiprows=1) - - return data[monob-offset_mb,:] - - ############# Temperature Parameters (K) ############# - - def heat(pulse_type: str, t:float) -> float: - """Returns the surface heat flux for a given pulse type - - Args: - pulse_type: pulse type (eg. FP, ICWC, RISP, GDC, BAKE) - - Raises: - ValueError: if the pulse type is unknown - - Returns: - the surface heat flux in W/m2 - """ - if pulse_type not in ["FP", "ICWC", "RISP", "GDC", "BAKE"]: - raise ValueError(f"Invalid pulse type {pulse_type}") - - if pulse_type == "RISP": - data = RISP_data(nb_mb, time=t) - else: - data = pulse_type_to_DINA_data[pulse_type] - - if pulse_type == "FP": heat_val = data[:, -2][nb_mb - 1] - elif pulse_type == "RISP": heat_val = data[-1] - else: heat_val = data[:, -1][nb_mb - 1] - - return heat_val - - def T_surface(t: dolfinx.fem.Constant) -> float: - """Monoblock surface temperature - - Args: - t: time in seconds - - Returns: - monoblock surface temperature in K - """ - pulse_type = my_scenario.get_pulse_type(float(t)) - pulse_row = my_scenario.get_row(float(t)) - time_elapsed = my_scenario.get_time_till_row(pulse_row) - return 1.1e-4 * heat(pulse_type, t=t-time_elapsed) + COOLANT_TEMP - - def T_rear(t: dolfinx.fem.Constant): - """Monoblock surface temperature - - Args: - t: time in seconds - - Returns: - monoblock surface temperature in K - """ - pulse_type = my_scenario.get_pulse_type(float(t)) - pulse_row = my_scenario.get_row(float(t)) - time_elapsed = my_scenario.get_time_till_row(pulse_row) - return 2.2e-5 * heat(pulse_type, t=t-time_elapsed) + COOLANT_TEMP + nb_mb = 64 + L = 6e-3 # m - def T_function(x, t: Constant): - """Monoblock temperature function + def T_function(x: NDArray, t: float) -> float: + """Monoblock temperature function. Args: x: position along monoblock @@ -298,238 +75,141 @@ def T_function(x, t: Constant): Returns: pulsed monoblock temperature in K """ - resting_value = np.full_like(x[0], COOLANT_TEMP) - pulse_row = my_scenario.get_row(float(t)) - pulse_type = my_scenario.get_pulse_type(float(t)) - - if pulse_type == "BAKE": - flat_top_value = 483.15 - else: - a = (T_rear(t) - T_surface(t)) / L - b = T_surface(t) - flat_top_value = a * x[0] + b + assert isinstance(t, float), f"t should be a float, not {type(t)}" + pulse = my_scenario.get_pulse(t) + t_rel = t - my_scenario.get_time_start_current_pulse(t) - total_time_on = my_scenario.get_pulse_duration_no_waiting(pulse_row) - total_time_pulse = my_scenario.get_pulse_duration(pulse_row) - time_elapsed = my_scenario.get_time_till_row(pulse_row) + if pulse.pulse_type == "BAKE": + T_bake = 483.15 # K + flat_top_value = np.full_like(x[0], T_bake) + else: + heat_flux = plasma_data_handling.heat(pulse.pulse_type, nb_mb, t_rel) + T_surface = 1.1e-4 * heat_flux + COOLANT_TEMP + T_rear = 2.2e-5 * heat_flux + COOLANT_TEMP + a = (T_rear - T_surface) / L + b = T_surface + flat_top_value = a * x[0] + b - return ( - flat_top_value - if (float(t)-time_elapsed) % total_time_pulse < total_time_on and (float(t)-time_elapsed) % total_time_pulse != 0.0 - else resting_value + total_time_on = pulse.duration_no_waiting + total_time_pulse = pulse.total_duration + return periodic_step_function( + t_rel, + period_on=total_time_on, + period_total=total_time_pulse, + value=flat_top_value, + value_off=np.full_like(x[0], COOLANT_TEMP), ) - # times = np.linspace(0, my_scenario.get_maximum_time(), num=100) - - # x = [0] - # Ts = [T_function(x, t) for t in times] - - # plt.plot(times, Ts, marker="o") - # plt.show() - - my_model.temperature = T_function - - ############# Flux Parameters ############# - - def get_flux(pulse_type, monob, t: float, ion=True): - FP_index = 2 - other_index = 0 - if not ion: - FP_index += FP_index+1 - other_index += other_index+1 - - if pulse_type == "FP": - flux = pulse_type_to_DINA_data[pulse_type][:, FP_index][monob - 1] - elif pulse_type == "RISP": - t_value = int(t.value) if isinstance(t, Constant) else int(t) - flux = RISP_data(monob=nb_mb, time=t_value)[other_index] - elif pulse_type == "BAKE": - flux = 0.0 - else: - flux = pulse_type_to_DINA_data[pulse_type][:, other_index][monob - 1] - - return flux - - def deuterium_ion_flux(t: float): - pulse_type = my_scenario.get_pulse_type(float(t)) - - pulse_row = my_scenario.get_row(float(t)) - total_time_on = my_scenario.get_pulse_duration_no_waiting(pulse_row) - total_time_pulse = my_scenario.get_pulse_duration(pulse_row) - time_elapsed = my_scenario.get_time_till_row(pulse_row) - - ion_flux = get_flux(pulse_type=pulse_type, monob=nb_mb, t=t-time_elapsed) + def deuterium_ion_flux(t: float) -> float: + assert isinstance(t, float), f"t should be a float, not {type(t)}" + pulse = my_scenario.get_pulse(t) + pulse_type = pulse.pulse_type + + total_time_on = pulse.duration_no_waiting + total_time_pulse = pulse.total_duration + time_start_current_pulse = my_scenario.get_time_start_current_pulse(t) + relative_time = t - time_start_current_pulse + + ion_flux = plasma_data_handling.get_particle_flux( + pulse_type=pulse_type, nb_mb=nb_mb, t_rel=relative_time, ion=True + ) tritium_fraction = PULSE_TYPE_TO_TRITIUM_FRACTION[pulse_type] flat_top_value = ion_flux * (1 - tritium_fraction) resting_value = 0 - - return ( - flat_top_value - if (float(t)-time_elapsed) % total_time_pulse < total_time_on and (float(t)-time_elapsed) % total_time_pulse != 0.0 - else resting_value + return periodic_step_function( + relative_time, + period_on=total_time_on, + period_total=total_time_pulse, + value=flat_top_value, + value_off=resting_value, ) - - # plt.plot(times, [deuterium_ion_flux(t) for t in times], marker="o") - # plt.show() - # exit() - - def tritium_ion_flux(t: float): - pulse_type = my_scenario.get_pulse_type(float(t)) - - pulse_row = my_scenario.get_row(float(t)) - total_time_on = my_scenario.get_pulse_duration_no_waiting(pulse_row) - total_time_pulse = my_scenario.get_pulse_duration(pulse_row) - time_elapsed = my_scenario.get_time_till_row(pulse_row) - - ion_flux = get_flux(pulse_type=pulse_type, monob=nb_mb, t=t-time_elapsed) - + + def tritium_ion_flux(t: float) -> float: + assert isinstance(t, float), f"t should be a float, not {type(t)}" + pulse = my_scenario.get_pulse(t) + pulse_type = pulse.pulse_type + + total_time_on = pulse.duration_no_waiting + total_time_pulse = pulse.total_duration + time_start_current_pulse = my_scenario.get_time_start_current_pulse(t) + relative_time = t - time_start_current_pulse + + ion_flux = plasma_data_handling.get_particle_flux( + pulse_type=pulse_type, nb_mb=nb_mb, t_rel=relative_time, ion=True + ) + tritium_fraction = PULSE_TYPE_TO_TRITIUM_FRACTION[pulse_type] flat_top_value = ion_flux * tritium_fraction - resting_value = 0 - return ( - flat_top_value - if (float(t)-time_elapsed) % total_time_pulse < total_time_on and (float(t)-time_elapsed) % total_time_pulse != 0.0 - else resting_value + resting_value = 0.0 + + return periodic_step_function( + relative_time, + period_on=total_time_on, + period_total=total_time_pulse, + value=flat_top_value, + value_off=resting_value, ) - def deuterium_atom_flux(t: float): - pulse_type = my_scenario.get_pulse_type(float(t)) + def deuterium_atom_flux(t: float) -> float: + assert isinstance(t, float), f"t should be a float, not {type(t)}" + pulse = my_scenario.get_pulse(t) + pulse_type = pulse.pulse_type - pulse_row = my_scenario.get_row(float(t)) - total_time_on = my_scenario.get_pulse_duration_no_waiting(pulse_row) - total_time_pulse = my_scenario.get_pulse_duration(pulse_row) - time_elapsed = my_scenario.get_time_till_row(pulse_row) - - atom_flux = get_flux(pulse_type=pulse_type, monob=nb_mb, t=t-time_elapsed, ion=False) - - tritium_fraction = PULSE_TYPE_TO_TRITIUM_FRACTION[pulse_type] - flat_top_value = atom_flux * (1 - tritium_fraction) - resting_value = 0 - return ( - flat_top_value - if (float(t)-time_elapsed) % total_time_pulse < total_time_on and (float(t)-time_elapsed) % total_time_pulse != 0.0 - else resting_value + total_time_on = pulse.duration_no_waiting + total_time_pulse = pulse.total_duration + time_start_current_pulse = my_scenario.get_time_start_current_pulse(t) + relative_time = t - time_start_current_pulse + + atom_flux = plasma_data_handling.get_particle_flux( + pulse_type=pulse_type, nb_mb=nb_mb, t_rel=relative_time, ion=False ) - def tritium_atom_flux(t: float): - pulse_type = my_scenario.get_pulse_type(float(t)) - - pulse_row = my_scenario.get_row(float(t)) - total_time_on = my_scenario.get_pulse_duration_no_waiting(pulse_row) - total_time_pulse = my_scenario.get_pulse_duration(pulse_row) - time_elapsed = my_scenario.get_time_till_row(pulse_row) - - atom_flux = get_flux(pulse_type=pulse_type, monob=nb_mb, t=t-time_elapsed, ion=False) tritium_fraction = PULSE_TYPE_TO_TRITIUM_FRACTION[pulse_type] - flat_top_value = atom_flux * tritium_fraction - resting_value = 0 - return ( - flat_top_value - if (float(t)-time_elapsed) % total_time_pulse < total_time_on and (float(t)-time_elapsed) % total_time_pulse != 0.0 - else resting_value + flat_top_value = atom_flux * (1 - tritium_fraction) + resting_value = 0.0 + return periodic_step_function( + relative_time, + period_on=total_time_on, + period_total=total_time_pulse, + value=flat_top_value, + value_off=resting_value, ) - my_model.sources = [ - PulsedSource( - flux=deuterium_ion_flux, - distribution=gaussian_distribution, - species=mobile_D, - volume=w_subdomain, - ), - PulsedSource( - flux=tritium_ion_flux, - distribution=gaussian_distribution, - species=mobile_T, - volume=w_subdomain, - ), - PulsedSource( - flux=deuterium_atom_flux, - distribution=gaussian_distribution, - species=mobile_D, - volume=w_subdomain, - ), - PulsedSource( - flux=tritium_atom_flux, - distribution=gaussian_distribution, - species=mobile_T, - volume=w_subdomain, - ), - ] - - ############# Boundary Conditions ############# - surface_reaction_dd = F.SurfaceReactionBC( - reactant=[mobile_D, mobile_D], - gas_pressure=0, - k_r0=7.94e-17, - E_kr=-2, - k_d0=0, - E_kd=0, - subdomain=inlet, - ) + def tritium_atom_flux(t: float) -> float: + assert isinstance(t, float), f"t should be a float, not {type(t)}" + pulse = my_scenario.get_pulse(t) + pulse_type = pulse.pulse_type - surface_reaction_tt = F.SurfaceReactionBC( - reactant=[mobile_T, mobile_T], - gas_pressure=0, - k_r0=7.94e-17, - E_kr=-2, - k_d0=0, - E_kd=0, - subdomain=inlet, - ) + total_time_on = pulse.duration_no_waiting + total_time_pulse = pulse.total_duration + time_start_current_pulse = my_scenario.get_time_start_current_pulse(t) + relative_time = t - time_start_current_pulse - surface_reaction_dt = F.SurfaceReactionBC( - reactant=[mobile_D, mobile_T], - gas_pressure=0, - k_r0=7.94e-17, - E_kr=-2, - k_d0=0, - E_kd=0, - subdomain=inlet, - ) + atom_flux = plasma_data_handling.get_particle_flux( + pulse_type=pulse_type, nb_mb=nb_mb, t_rel=relative_time, ion=False + ) + tritium_fraction = PULSE_TYPE_TO_TRITIUM_FRACTION[pulse_type] + flat_top_value = atom_flux * tritium_fraction + resting_value = 0.0 + return periodic_step_function( + relative_time, + period_on=total_time_on, + period_total=total_time_pulse, + value=flat_top_value, + value_off=resting_value, + ) - my_model.boundary_conditions = [ - surface_reaction_dd, - surface_reaction_dt, - surface_reaction_tt, - ] - - ############# Exports ############# - - folder = f"mb{mb}_results" - - my_model.exports = [ - F.VTXExport(f"{folder}/mobile_concentration_t.bp", field=mobile_T), - F.VTXExport(f"{folder}/mobile_concentration_d.bp", field=mobile_D), - F.VTXExport(f"{folder}/trapped_concentration_d1.bp", field=trap1_D), - F.VTXExport(f"{folder}/trapped_concentration_t1.bp", field=trap1_T), - F.VTXExport(f"{folder}/trapped_concentration_d2.bp", field=trap2_D), - F.VTXExport(f"{folder}/trapped_concentration_t2.bp", field=trap2_T), - F.VTXExport(f"{folder}/trapped_concentration_d3.bp", field=trap3_D), - F.VTXExport(f"{folder}/trapped_concentration_t3.bp", field=trap3_T), - ] - - quantities = {} - for species in my_model.species: - quantity = F.TotalVolume(field=species, volume=w_subdomain) - my_model.exports.append(quantity) - quantities[species.name] = quantity - - ############# Settings ############# - my_model.settings = F.Settings( - atol=1e-15, - rtol=1e-15, - max_iterations=1000, - final_time=my_scenario.get_maximum_time() + my_model, quantities = make_mb_model( + temperature=T_function, + deuterium_ion_flux=deuterium_ion_flux, + tritium_ion_flux=tritium_ion_flux, + deuterium_atom_flux=deuterium_atom_flux, + tritium_atom_flux=tritium_atom_flux, + # FIXME: -1s here to avoid last time step spike + final_time=my_scenario.get_maximum_time()-1, + L=6e-3, + folder=f"mb{nb_mb}_results", ) - - my_model.settings.stepsize = F.Stepsize(initial_value=1) - - return my_model, quantities - - -if __name__ == "__main__": - my_model, quantities = make_mb_model(nb_mb=mb, scenario_file="scenario_test.txt") - ############# Run Simu ############# my_model.initialise() @@ -539,7 +219,7 @@ def tritium_atom_flux(t: float): ############# Results Plotting ############# for name, quantity in quantities.items(): - plt.plot(quantity.t, quantity.data, label=name) + plt.plot(quantity.t, quantity.data, label=name, marker="o") plt.xlabel("Time (s)") plt.ylabel("Total quantity (atoms/m2)") @@ -548,8 +228,6 @@ def tritium_atom_flux(t: float): plt.show() - # make the same but with a stack plot - fig, ax = plt.subplots() ax.stackplot( @@ -561,4 +239,4 @@ def tritium_atom_flux(t: float): plt.xlabel("Time (s)") plt.ylabel("Total quantity (atoms/m2)") plt.legend() - # plt.show() + plt.show() diff --git a/one_line_scenario.txt b/one_line_scenario.txt deleted file mode 100644 index 328054b..0000000 --- a/one_line_scenario.txt +++ /dev/null @@ -1,2 +0,0 @@ -# PULSE TYPE, NUMBER OF PULSES, RAMP UP, RAMP DOWN, STEADY STATE, WAITING -FP 2 455 455 650 1000 \ No newline at end of file diff --git a/src/hisp/__init__.py b/src/hisp/__init__.py index 391c7d9..bfdbbf4 100644 --- a/src/hisp/__init__.py +++ b/src/hisp/__init__.py @@ -1,3 +1,6 @@ -from .helpers import PulsedSource, Scenario +from .helpers import PulsedSource, gaussian_distribution, periodic_step_function from .h_transport_class import CustomProblem + +from .festim_models.mb_model import make_mb_model +from .scenario import Scenario, Pulse diff --git a/src/hisp/festim_models/__init__.py b/src/hisp/festim_models/__init__.py new file mode 100644 index 0000000..c70dbda --- /dev/null +++ b/src/hisp/festim_models/__init__.py @@ -0,0 +1 @@ +from .mb_model import make_mb_model \ No newline at end of file diff --git a/src/hisp/festim_models/mb_model.py b/src/hisp/festim_models/mb_model.py new file mode 100644 index 0000000..8c8fb51 --- /dev/null +++ b/src/hisp/festim_models/mb_model.py @@ -0,0 +1,276 @@ +from hisp.h_transport_class import CustomProblem +from hisp.helpers import PulsedSource, gaussian_distribution + +import numpy as np +import festim as F +import h_transport_materials as htm + +from typing import Callable, Tuple, Dict + +# TODO this is hard coded and show depend on incident energy? +implantation_range = 3e-9 # m +width = 1e-9 # m + +def make_mb_model( + temperature: Callable | float | int, + deuterium_ion_flux: Callable, + tritium_ion_flux: Callable, + deuterium_atom_flux: Callable, + tritium_atom_flux: Callable, + final_time: float, + folder: str, + L: float = 6e-3, +) -> Tuple[CustomProblem, Dict[str, F.TotalVolume]]: + """Create a FESTIM model for the MB scenario. + + Args: + temperature: the temperature in K. + deuterium_ion_flux: the deuterium ion flux in m^-2 s^-1. + tritium_ion_flux: the tritium ion flux in m^-2 s^-1. + deuterium_atom_flux: the deuterium atom flux in m^-2 s^-1. + tritium_atom_flux: the tritium atom flux in m^-2 s^-1. + final_time: the final time in s. + folder: the folder to save the results. + L: the length of the domain in m. + + Returns: + the FESTIM model, the quantities to export. + """ + my_model = CustomProblem() + + ############# Material Parameters ############# + + L = 6e-3 # m + vertices = np.concatenate( # 1D mesh with extra refinement + [ + np.linspace(0, 30e-9, num=200), + np.linspace(30e-9, 3e-6, num=300), + np.linspace(3e-6, 30e-6, num=200), + np.linspace(30e-6, L, num=200), + ] + ) + my_model.mesh = F.Mesh1D(vertices) + + # W material parameters + w_density = 6.3382e28 # atoms/m3 + w_diffusivity = ( + htm.diffusivities.filter(material="tungsten") + .filter(isotope="h") + .filter(author="frauenfelder") + ) + w_diffusivity = w_diffusivity[0] + D_0 = w_diffusivity.pre_exp.magnitude + E_D = w_diffusivity.act_energy.magnitude + tungsten = F.Material( + D_0=D_0, + E_D=E_D, + name="tungsten", + ) + + # mb subdomains + w_subdomain = F.VolumeSubdomain1D(id=1, borders=[0, L], material=tungsten) + inlet = F.SurfaceSubdomain1D(id=1, x=0) + outlet = F.SurfaceSubdomain1D(id=2, x=L) + + my_model.subdomains = [w_subdomain, inlet, outlet] + + # hydrogen species + mobile_D = F.Species("D") + mobile_T = F.Species("T") + + trap1_D = F.Species("trap1_D", mobile=False) + trap1_T = F.Species("trap1_T", mobile=False) + trap2_D = F.Species("trap2_D", mobile=False) + trap2_T = F.Species("trap2_T", mobile=False) + trap3_D = F.Species("trap3_D", mobile=False) + trap3_T = F.Species("trap3_T", mobile=False) + + # traps + empty_trap1 = F.ImplicitSpecies( # implicit trap 1 + n=6.338e24, # 1e-4 at.fr. + others=[trap1_T, trap1_D], + name="empty_trap1", + ) + + empty_trap2 = F.ImplicitSpecies( # implicit trap 2 + n=6.338e24, + others=[trap2_T, trap2_D], + name="empty_trap2", + ) + + # density_func = + empty_trap3 = F.ImplicitSpecies( # not implicit, but can simplify trap creation model to small damanged zone in first 10nm + n=6.338e27, # 1e-1 at.fr. + others=[trap3_T, trap3_D], + name="empty_trap3", + ) + + my_model.species = [ + mobile_D, + mobile_T, + trap1_D, + trap1_T, + trap2_D, + trap2_T, + trap3_D, + trap3_T, + ] + + # hydrogen reactions - 1 per trap per species + my_model.reactions = [ + F.Reaction( + k_0=D_0 / (1.1e-10**2 * 6 * w_density), + E_k=E_D, + p_0=1e13, + E_p=0.85, + volume=w_subdomain, + reactant=[mobile_D, empty_trap1], + product=trap1_D, + ), + F.Reaction( + k_0=D_0 / (1.1e-10**2 * 6 * w_density), + E_k=E_D, + p_0=1e13, + E_p=0.85, + volume=w_subdomain, + reactant=[mobile_T, empty_trap1], + product=trap1_T, + ), + F.Reaction( + k_0=D_0 / (1.1e-10**2 * 6 * w_density), + E_k=E_D, + p_0=1e13, + E_p=1, + volume=w_subdomain, + reactant=[mobile_D, empty_trap2], + product=trap2_D, + ), + F.Reaction( + k_0=D_0 / (1.1e-10**2 * 6 * w_density), + E_k=E_D, + p_0=1e13, + E_p=1, + volume=w_subdomain, + reactant=[mobile_T, empty_trap2], + product=trap2_T, + ), + F.Reaction( + k_0=D_0 / (1.1e-10**2 * 6 * w_density), + E_k=E_D, + p_0=1e13, + E_p=1.5, + volume=w_subdomain, + reactant=[mobile_D, empty_trap3], + product=trap3_D, + ), + F.Reaction( + k_0=D_0 / (1.1e-10**2 * 6 * w_density), + E_k=E_D, + p_0=1e13, + E_p=1.5, + volume=w_subdomain, + reactant=[mobile_T, empty_trap3], + product=trap3_T, + ), + ] + + ############# Temperature Parameters (K) ############# + + my_model.temperature = temperature + + ############# Flux Parameters ############# + + my_model.sources = [ + PulsedSource( + flux=deuterium_ion_flux, + distribution=lambda x: gaussian_distribution(x, implantation_range, width), + species=mobile_D, + volume=w_subdomain, + ), + PulsedSource( + flux=tritium_ion_flux, + distribution=lambda x: gaussian_distribution(x, implantation_range, width), + species=mobile_T, + volume=w_subdomain, + ), + PulsedSource( + flux=deuterium_atom_flux, + distribution=lambda x: gaussian_distribution(x, implantation_range, width), + species=mobile_D, + volume=w_subdomain, + ), + PulsedSource( + flux=tritium_atom_flux, + distribution=lambda x: gaussian_distribution(x, implantation_range, width), + species=mobile_T, + volume=w_subdomain, + ), + ] + + ############# Boundary Conditions ############# + surface_reaction_dd = F.SurfaceReactionBC( + reactant=[mobile_D, mobile_D], + gas_pressure=0, + k_r0=7.94e-17, + E_kr=-2, + k_d0=0, + E_kd=0, + subdomain=inlet, + ) + + surface_reaction_tt = F.SurfaceReactionBC( + reactant=[mobile_T, mobile_T], + gas_pressure=0, + k_r0=7.94e-17, + E_kr=-2, + k_d0=0, + E_kd=0, + subdomain=inlet, + ) + + surface_reaction_dt = F.SurfaceReactionBC( + reactant=[mobile_D, mobile_T], + gas_pressure=0, + k_r0=7.94e-17, + E_kr=-2, + k_d0=0, + E_kd=0, + subdomain=inlet, + ) + + my_model.boundary_conditions = [ + surface_reaction_dd, + surface_reaction_dt, + surface_reaction_tt, + ] + + ############# Exports ############# + + my_model.exports = [ + F.VTXExport(f"{folder}/mobile_concentration_t.bp", field=mobile_T), + F.VTXExport(f"{folder}/mobile_concentration_d.bp", field=mobile_D), + F.VTXExport(f"{folder}/trapped_concentration_d1.bp", field=trap1_D), + F.VTXExport(f"{folder}/trapped_concentration_t1.bp", field=trap1_T), + F.VTXExport(f"{folder}/trapped_concentration_d2.bp", field=trap2_D), + F.VTXExport(f"{folder}/trapped_concentration_t2.bp", field=trap2_T), + F.VTXExport(f"{folder}/trapped_concentration_d3.bp", field=trap3_D), + F.VTXExport(f"{folder}/trapped_concentration_t3.bp", field=trap3_T), + ] + + quantities = {} + for species in my_model.species: + quantity = F.TotalVolume(field=species, volume=w_subdomain) + my_model.exports.append(quantity) + quantities[species.name] = quantity + + ############# Settings ############# + my_model.settings = F.Settings( + atol=1e-15, + rtol=1e-15, + max_iterations=1000, + final_time=final_time, + ) + + my_model.settings.stepsize = F.Stepsize(initial_value=1) + + return my_model, quantities diff --git a/src/hisp/h_transport_class.py b/src/hisp/h_transport_class.py index f722739..bc952ef 100644 --- a/src/hisp/h_transport_class.py +++ b/src/hisp/h_transport_class.py @@ -33,7 +33,6 @@ def define_temperature(self): mesh=self.mesh.mesh, value=self.temperature(t=float(self.t)) ) else: - x = ufl.SpatialCoordinate(self.mesh.mesh) degree = 1 element_temperature = basix.ufl.element( basix.ElementFamily.P, diff --git a/src/hisp/helpers.py b/src/hisp/helpers.py index 43b18b2..1b91471 100644 --- a/src/hisp/helpers.py +++ b/src/hisp/helpers.py @@ -2,6 +2,7 @@ from dolfinx.fem.function import Constant import ufl import numpy as np +import numpy.typing as npt class PulsedSource(F.ParticleSource): @@ -9,7 +10,7 @@ def __init__(self, flux, distribution, volume, species): """Initalizes flux and distribution for PulsedSource. Args: - flux (float): the input flux value from DINA data + flux (callable): the input flux value from DINA data distribution (function of x): distribution of flux throughout mb volume (F.VolumeSubdomain1D): volume where this flux is imposed species (F.species): species of flux (e.g. D/T) @@ -26,7 +27,7 @@ def time_dependent(self): return True def create_value_fenics(self, mesh, temperature, t: Constant): - self.flux_fenics = Constant(mesh, float(self.flux(t))) + self.flux_fenics = F.as_fenics_constant(self.flux(float(t)), mesh) x = ufl.SpatialCoordinate(mesh) self.distribution_fenics = self.distribution(x) @@ -35,119 +36,18 @@ def create_value_fenics(self, mesh, temperature, t: Constant): def update(self, t: float): self.flux_fenics.value = self.flux(t) +def gaussian_distribution(x: npt.NDArray, mean:float, width:float, mod=ufl) -> ufl.core.expr.Expr: + return mod.exp(-((x[0] - mean) ** 2) / (2 * width**2)) -class Scenario: - def __init__(self, filename: str): - self.filename = filename - data = np.genfromtxt(filename, dtype=str, comments="#") - if isinstance(data[0], str): - self.data = [data] - else: - self.data = data +def periodic_step_function(x, period_on, period_total, value, value_off=0.0): + """ + Creates a periodic step function with two periods. + """ - def get_row(self, t: float): - """Returns the row of the scenario file that corresponds to the time t. + if period_total < period_on: + raise ValueError("period_total must be greater than period_on") - Args: - t (float): the time in seconds - - Returns: - int: the row index of the scenario file corresponding to the time t - """ - current_time = 0 - for i, row in enumerate(self.data): - nb_pulses = int(row[1]) - phase_duration = nb_pulses * self.get_pulse_duration(i) - if t <= current_time + phase_duration: - return i - else: - current_time += phase_duration - - raise ValueError( - f"Time t {t} is out of bounds of the scenario file. Maximum time is {self.get_maximum_time()}" - ) - - def get_pulse_type(self, t: float) -> str: - """Returns the pulse type as a string at time t. - - Args: - t (float): time in seconds - - Returns: - str: pulse type (eg. FP, ICWC, RISP, GDC, BAKE) - """ - row_idx = self.get_row(t) - return self.data[row_idx][0] - - def get_pulse_duration(self, row: int) -> float: - """Returns the total duration of a pulse in seconds for a given row in the file. - - Args: - row (int): the row index in the scenario file - - Returns: - float: the total duration of the pulse in seconds - """ - row_data = self.data[row] - pulse_type = row_data[0] - if pulse_type == "RISP": # hard coded because it's zero in the files - ramp_up = 10 - steady_state = 250 - ramp_down = 10 - waiting = 1530 - total_duration = ramp_up + steady_state + ramp_down + waiting - return total_duration - - ramp_up = float(row_data[2]) - steady_state = float(row_data[4]) - ramp_down = float(row_data[3]) - waiting = float(row_data[5]) - - total_duration = ramp_up + steady_state + ramp_down + waiting - return total_duration - - def get_pulse_duration_no_waiting(self, row: int) -> float: - """Returns the total duration (without the waiting time) of a pulse in seconds for a given row in the file. - - Args: - row (int): the row index in the scenario file - - Returns: - float: the total duration of the pulse in seconds - """ - row_data = self.data[row] - pulse_type = row_data[0] - if pulse_type == "RISP": # hard coded because it's zero in the files - waiting_time = 1530 - else: - waiting_time = float(row_data[5]) - - duration = self.get_pulse_duration(row) - waiting_time - return duration - - def get_time_till_row(self, row:int) -> float: - """Returns the time that has elapsed in scenario up until start of current row. - - Args: - row (int): the row index in the scenario file - - Returns: - float: the time that has elapsed in scenario until and not including input row. - """ - time_elapsed = 0 - for prev_row_id in range(0,row): - nb_pulses = int(self.data[prev_row_id][1]) - time_elapsed += nb_pulses * self.get_pulse_duration(prev_row_id) - return time_elapsed - - def get_maximum_time(self) -> float: - """Returns the maximum time in seconds for the scenario file. - - Returns: - float: the maximum time in seconds - """ - max_time = 0 - for i, row in enumerate(self.data): - nb_pulses = int(row[1]) - max_time += nb_pulses * self.get_pulse_duration(i) - return max_time + if x % period_total < period_on: + return value + else: + return value_off \ No newline at end of file diff --git a/src/hisp/plamsa_data_handling/__init__.py b/src/hisp/plamsa_data_handling/__init__.py new file mode 100644 index 0000000..b1e6698 --- /dev/null +++ b/src/hisp/plamsa_data_handling/__init__.py @@ -0,0 +1 @@ +from .main import PlasmaDataHandling \ No newline at end of file diff --git a/src/hisp/plamsa_data_handling/main.py b/src/hisp/plamsa_data_handling/main.py new file mode 100644 index 0000000..2782c85 --- /dev/null +++ b/src/hisp/plamsa_data_handling/main.py @@ -0,0 +1,161 @@ +import numpy as np +from numpy.typing import NDArray + +from typing import Dict + + +class PlasmaDataHandling: + def __init__( + self, + pulse_type_to_data: Dict[str, NDArray], + path_to_RISP_data: str, + path_to_ROSP_data: str, + path_to_RISP_wall_data: str, + ): + self.pulse_type_to_data = pulse_type_to_data + self.path_to_RISP_data = path_to_RISP_data + self.path_to_ROSP_data = path_to_ROSP_data + self.path_to_RISP_wall_data = path_to_RISP_wall_data + + self._time_to_RISP_data = {} + + def get_particle_flux( + self, pulse_type: str, nb_mb: int, t_rel: float, ion=True + ) -> float: + """Returns the particle flux for a given pulse type + + Args: + pulse_type: pulse type (eg. FP, ICWC, RISP, GDC, BAKE) + nb_mb: monoblock number + t_rel: t_rel as an integer (in seconds). + t_rel = t - t_pulse_start where t_pulse_start is the start of the pulse in seconds + ion (bool, optional): _description_. Defaults to True. + + Returns: + float: particle flux in part/m2/s + """ + if ion: + FP_index = 2 + other_index = 0 + if not ion: + FP_index = 3 + other_index = 1 + + if pulse_type == "FP": + flux = self.pulse_type_to_data[pulse_type][:, FP_index][nb_mb - 1] + elif pulse_type == "RISP": + assert isinstance( + t_rel, float + ), f"t_rel should be a float, not {type(t_rel)}" + flux = self.RISP_data(nb_mb=nb_mb, t_rel=t_rel)[other_index] + elif pulse_type == "BAKE": + flux = 0.0 + else: + flux = self.pulse_type_to_data[pulse_type][:, other_index][nb_mb - 1] + + return flux + + def RISP_data(self, nb_mb: int, t_rel: float | int) -> NDArray: + """Returns the correct RISP data file for indicated monoblock + + Args: + nb_mb: mb number + t_rel: t_rel as an integer(in seconds). + t_rel = t - t_pulse_start where t_pulse_start is the start of the pulse in seconds + + Returns: + data: data from correct file as a numpy array + """ + inner_swept_bins = list(range(46, 65)) + outer_swept_bins = list(range(19, 34)) + + if nb_mb in inner_swept_bins: + folder = self.path_to_RISP_data + div = True + offset_mb = 46 + elif nb_mb in outer_swept_bins: + folder = self.path_to_ROSP_data + div = True + offset_mb = 19 + else: + div = False + offset_mb = 0 + + t_rel = int(t_rel) + # NOTE: what is the point of this test since it takes nb_mb as an argument? + if div: + if 1 <= t_rel <= 9: + key = f"{folder}_1_9" + if key not in self._time_to_RISP_data.keys(): + self._time_to_RISP_data[key] = np.loadtxt( + f"{folder}/time0.dat", skiprows=1 + ) + data = self._time_to_RISP_data[key] + elif 10 <= t_rel <= 98: + key = f"{folder}_10_98" + if key not in self._time_to_RISP_data.keys(): + self._time_to_RISP_data[key] = np.loadtxt( + f"{folder}/time10.dat", skiprows=1 + ) + data = self._time_to_RISP_data[key] + elif 100 <= t_rel <= 260: + key = f"{folder}_{t_rel}" + if key not in self._time_to_RISP_data.keys(): + self._time_to_RISP_data[key] = np.loadtxt( + f"{folder}/time{t_rel}.dat", skiprows=1 + ) + data = self._time_to_RISP_data[key] + elif 261 <= t_rel <= 269: + key = f"{folder}_261_269" + if key not in self._time_to_RISP_data.keys(): + self._time_to_RISP_data[key] = np.loadtxt( + f"{folder}/time260.dat", skiprows=1 + ) + data = self._time_to_RISP_data[key] + else: # NOTE: so if time is too large a MB transforms into a FW element??? + key = "wall_data" + if key not in self._time_to_RISP_data.keys(): + self._time_to_RISP_data[key] = np.loadtxt( + self.path_to_RISP_wall_data, skiprows=1 + ) + data = self._time_to_RISP_data[key] + else: + key = "wall_data" + if key not in self._time_to_RISP_data.keys(): + self._time_to_RISP_data[key] = np.loadtxt( + self.path_to_RISP_wall_data, skiprows=1 + ) + data = self._time_to_RISP_data[key] + + return data[nb_mb - offset_mb, :] + + def heat(self, pulse_type: str, nb_mb: int, t_rel: float) -> float: + """Returns the surface heat flux (W/m2) for a given pulse type + + Args: + pulse_type: pulse type (eg. FP, ICWC, RISP, GDC, BAKE) + nb_mb: monoblock number + t_rel: t_rel as an integer (in seconds). + t_rel = t - t_pulse_start where t_pulse_start is the start of the pulse in seconds + + Raises: + ValueError: if the pulse type is unknown + + Returns: + the surface heat flux in W/m2 + """ + if pulse_type == "RISP": + data = self.RISP_data(nb_mb, t_rel=t_rel) + elif pulse_type in self.pulse_type_to_data.keys(): + data = self.pulse_type_to_data[pulse_type] + else: + raise ValueError(f"Invalid pulse type {pulse_type}") + + if pulse_type == "FP": + heat_val = data[:, -2][nb_mb - 1] + elif pulse_type == "RISP": + heat_val = data[-1] + else: + heat_val = data[:, -1][nb_mb - 1] + + return heat_val diff --git a/src/hisp/scenario.py b/src/hisp/scenario.py new file mode 100644 index 0000000..e752d35 --- /dev/null +++ b/src/hisp/scenario.py @@ -0,0 +1,233 @@ +import pandas as pd +from typing import List +import warnings + + +class Pulse: + pulse_type: str + nb_pulses: int + ramp_up: float + steady_state: float + ramp_down: float + waiting: float + + def __init__( + self, + pulse_type: str, + nb_pulses: int, + ramp_up: float, + steady_state: float, + ramp_down: float, + waiting: float, + ): + self.pulse_type = pulse_type + self.nb_pulses = nb_pulses + self.ramp_up = ramp_up + self.steady_state = steady_state + self.ramp_down = ramp_down + self.waiting = waiting + + @property + def total_duration(self) -> float: + all_zeros = ( + self.ramp_up == 0 + and self.steady_state == 0 + and self.ramp_down == 0 + and self.waiting == 0 + ) + if self.pulse_type == "RISP" and all_zeros: + msg = "RISP pulse has all zeros for ramp_up, steady_state, ramp_down, waiting. " + msg += "Setting hardcoded values. Please check the values in the scenario file." + warnings.warn(msg, UserWarning) + + self.ramp_up = 10 + self.steady_state = 250 + self.ramp_down = 10 + self.waiting = 1530 + + return self.ramp_up + self.steady_state + self.ramp_down + self.waiting + + @property + def duration_no_waiting(self) -> float: + return self.total_duration - self.waiting + + +class Scenario: + def __init__(self, pulses: List[Pulse] = None): + """Initializes a Scenario object containing several pulses. + + Args: + pulses: The list of pulses in the scenario. Each pulse is a Pulse object. + """ + self._pulses = pulses if pulses is not None else [] + + @property + def pulses(self) -> List[Pulse]: + return self._pulses + + def to_txt_file(self, filename: str): + df = pd.DataFrame( + [ + { + "pulse_type": pulse.pulse_type, + "nb_pulses": pulse.nb_pulses, + "ramp_up": pulse.ramp_up, + "steady_state": pulse.steady_state, + "ramp_down": pulse.ramp_down, + "waiting": pulse.waiting, + } + for pulse in self.pulses + ] + ) + df.to_csv(filename, index=False) + + @staticmethod + def from_txt_file(filename: str, old_format=False) -> "Scenario": + if old_format: + pulses = [] + with open(filename, "r") as f: + for line in f: + # skip first line + if line.startswith("#"): + continue + + # skip empty lines + if not line.strip(): + continue + + # assume this is the format + pulse_type, nb_pulses, ramp_up, steady_state, ramp_down, waiting = ( + line.split() + ) + pulses.append( + Pulse( + pulse_type=pulse_type, + nb_pulses=int(nb_pulses), + ramp_up=float(ramp_up), + steady_state=float(steady_state), + ramp_down=float(ramp_down), + waiting=float(waiting), + ) + ) + return Scenario(pulses) + df = pd.read_csv(filename) + pulses = [ + Pulse( + pulse_type=row["pulse_type"], + nb_pulses=int(row["nb_pulses"]), + ramp_up=float(row["ramp_up"]), + steady_state=float(row["steady_state"]), + ramp_down=float(row["ramp_down"]), + waiting=float(row["waiting"]), + ) + for _, row in df.iterrows() + ] + return Scenario(pulses) + + def get_row(self, t: float) -> int: + """Returns the index of the pulse at time t. + + Args: + t: the time in seconds + + Returns: + the index of the pulse at time t + """ + current_time = 0 + for i, pulse in enumerate(self.pulses): + phase_duration = pulse.nb_pulses * pulse.total_duration + if t < current_time + phase_duration: + return i + else: + current_time += phase_duration + + raise ValueError( + f"Time t {t} is out of bounds of the scenario file. Valid times are t < {self.get_maximum_time()}" + ) + + def get_pulse(self, t: float) -> Pulse: + """Returns the pulse at time t. + + Args: + t: the time in seconds + + Returns: + Pulse: the pulse at time t + """ + row_idx = self.get_row(t) + return self.pulses[row_idx] + + def get_pulse_type(self, t: float) -> str: + """Returns the pulse type as a string at time t. + + Args: + t: time in seconds + + Returns: + pulse type (eg. FP, ICWC, RISP, GDC, BAKE) + """ + return self.get_pulse(t).pulse_type + + def get_maximum_time(self) -> float: + """Returns the maximum time of the scenario in seconds. + + Returns: + the maximum time of the scenario in seconds + """ + return sum([pulse.nb_pulses * pulse.total_duration for pulse in self.pulses]) + + def get_time_start_current_pulse(self, t: float): + """Returns the time (s) at which the current pulse started. + + Args: + t: the time in seconds + + Returns: + the time at which the current pulse started + """ + current_pulse = self.get_pulse(t) + pulse_index = self.pulses.index(current_pulse) + return sum( + [ + pulse.nb_pulses * pulse.total_duration + for pulse in self.pulses[:pulse_index] + ] + ) + + # TODO this is the same as get_time_start_current_pulse, remove + def get_time_till_row(self, row: int) -> float: + """Returns the time (s) until the row in the scenario file. + + Args: + row: the row index in the scenario file + + Returns: + the time until the row in the scenario file + """ + return sum( + [pulse.nb_pulses * pulse.total_duration for pulse in self.pulses[:row]] + ) + + # TODO remove + def get_pulse_duration_no_waiting(self, row: int) -> float: + """Returns the total duration (without the waiting time) of a pulse in seconds for a given row in the file. + + Args: + row: the row index in the scenario file + + Returns: + the total duration of the pulse in seconds + """ + return self.pulses[row].duration_no_waiting + + # TODO remove + def get_pulse_duration(self, row: int) -> float: + """Returns the total duration of a pulse in seconds for a given row in the file. + + Args: + row: the row index in the scenario file + + Returns: + the total duration of the pulse in seconds + """ + return self.pulses[row].total_duration diff --git a/test/one_line_scenario.txt b/test/one_line_scenario.txt deleted file mode 100644 index 328054b..0000000 --- a/test/one_line_scenario.txt +++ /dev/null @@ -1,2 +0,0 @@ -# PULSE TYPE, NUMBER OF PULSES, RAMP UP, RAMP DOWN, STEADY STATE, WAITING -FP 2 455 455 650 1000 \ No newline at end of file diff --git a/test/scenario_test.txt b/test/scenario_test.txt deleted file mode 100644 index 15ff0dc..0000000 --- a/test/scenario_test.txt +++ /dev/null @@ -1,3 +0,0 @@ -# PULSE TYPE, NUMBER OF PULSES, RAMP UP, RAMP DOWN, STEADY STATE, WAITING -FP 2 455 455 650 1000 -ICWC 2 36 36 180 1000 \ No newline at end of file diff --git a/test/test_mb_model_festim.py b/test/test_mb_model_festim.py new file mode 100644 index 0000000..34b87ce --- /dev/null +++ b/test/test_mb_model_festim.py @@ -0,0 +1,29 @@ +from hisp.festim_models.mb_model import make_mb_model + +import festim as F + +import pytest + + +@pytest.mark.parametrize("temp", [400, lambda t: 400 + 1, lambda x, t: 400 + t - x[0]]) +def test_mb_model(temp): + """Builds a festim model, run it, and tests the output.""" + (mb_model, quantities) = make_mb_model( + temperature=temp, + deuterium_ion_flux=lambda _: 1e22, + deuterium_atom_flux=lambda _: 1e22, + tritium_ion_flux=lambda _: 1e22, + tritium_atom_flux=lambda _: 1e22, + final_time=50, + folder=".", + ) + + mb_model.initialise() + mb_model.run() + + # TEST + assert isinstance(quantities, dict) + for key, value in quantities.items(): + assert isinstance(key, str) + assert isinstance(value, F.TotalVolume) + assert len(value.data) > 0 diff --git a/test/test_pulse.py b/test/test_pulse.py new file mode 100644 index 0000000..e5445be --- /dev/null +++ b/test/test_pulse.py @@ -0,0 +1,87 @@ +from hisp import Pulse + +import pytest + +def test_pulse_initialization(): + pulse = Pulse( + pulse_type="FP", + nb_pulses=2, + ramp_up=0.1, + steady_state=0.2, + ramp_down=0.3, + waiting=0.4, + ) + + assert pulse.pulse_type == "FP" + assert pulse.nb_pulses == 2 + assert pulse.ramp_up == 0.1 + assert pulse.steady_state == 0.2 + assert pulse.ramp_down == 0.3 + assert pulse.waiting == 0.4 + + +def test_pulse_total_duration(): + pulse = Pulse( + pulse_type="FP", + nb_pulses=2, + ramp_up=0.1, + steady_state=0.2, + ramp_down=0.3, + waiting=0.4, + ) + + assert pulse.total_duration == 1.0 + + +def test_pulse_total_duration_with_zeros(): + pulse = Pulse( + pulse_type="RISP", + nb_pulses=1, + ramp_up=0.0, + steady_state=0.0, + ramp_down=0.0, + waiting=0.0, + ) + + assert pulse.total_duration == 1800.0 + +def test_pulse_total_duration_no_waiting_with_zeros(): + pulse = Pulse( + pulse_type="RISP", + nb_pulses=1, + ramp_up=0.0, + steady_state=0.0, + ramp_down=0.0, + waiting=0.0, + ) + + assert pulse.duration_no_waiting == 270.0 + +def test_pulse_risp_with_zeros_raises_warning(): + with pytest.warns(UserWarning): + pulse = Pulse( + pulse_type="RISP", + nb_pulses=1, + ramp_up=0.0, + steady_state=0.0, + ramp_down=0.0, + waiting=0.0, + ) + pulse.total_duration + assert pulse.ramp_up != 0.0 + assert pulse.steady_state != 0.0 + assert pulse.ramp_down != 0.0 + assert pulse.waiting != 0.0 + +def test_pulse_duration_no_waiting(): + pulse = Pulse( + pulse_type="FP", + nb_pulses=2, + ramp_up=0.1, + steady_state=0.2, + ramp_down=0.3, + waiting=0.4, + ) + + assert pulse.duration_no_waiting == 0.6 + assert pulse.duration_no_waiting == pulse.total_duration - pulse.waiting \ No newline at end of file diff --git a/test/test_scenario.py b/test/test_scenario.py index 2ad8fe0..57b94d3 100644 --- a/test/test_scenario.py +++ b/test/test_scenario.py @@ -1,17 +1,125 @@ -from hisp import Scenario -import os +from hisp.scenario import Scenario, Pulse import pytest -import numpy as np import matplotlib.pyplot as plt +import numpy as np -current_dir = os.path.dirname(__file__) -scenario_path = os.path.join(current_dir, "scenario_test.txt") -one_line_scenario_path = os.path.join(current_dir, "one_line_scenario.txt") + +def test_scenario(): + scenario = Scenario() + assert len(scenario.pulses) == 0 + + scenario.pulses.append( + Pulse( + pulse_type="FP", + nb_pulses=2, + ramp_up=0.1, + steady_state=0.2, + ramp_down=0.3, + waiting=0.4, + ) + ) + + assert len(scenario.pulses) == 1 + assert scenario.pulses[0].pulse_type == "FP" + assert scenario.pulses[0].nb_pulses == 2 + assert scenario.pulses[0].ramp_up == 0.1 + assert scenario.pulses[0].steady_state == 0.2 + assert scenario.pulses[0].ramp_down == 0.3 + assert scenario.pulses[0].waiting == 0.4 + + scenario.to_txt_file("test_scenario.txt") + scenario2 = Scenario.from_txt_file("test_scenario.txt") + + assert len(scenario2.pulses) == 1 + assert scenario2.pulses[0].pulse_type == "FP" + assert scenario2.pulses[0].nb_pulses == 2 + assert scenario2.pulses[0].ramp_up == 0.1 + assert scenario2.pulses[0].steady_state == 0.2 + assert scenario2.pulses[0].ramp_down == 0.3 + assert scenario2.pulses[0].waiting == 0.4 + + +def test_scenario_several_pulses(): + scenario = Scenario() + assert len(scenario.pulses) == 0 + + scenario.pulses.append( + Pulse( + pulse_type="FP", + nb_pulses=2, + ramp_up=0.1, + steady_state=0.2, + ramp_down=0.3, + waiting=0.4, + ) + ) + + scenario.pulses.append( + Pulse( + pulse_type="ICWC", + nb_pulses=3, + ramp_up=0.5, + steady_state=0.6, + ramp_down=0.7, + waiting=0.8, + ) + ) + + assert len(scenario.pulses) == 2 + assert scenario.pulses[0].pulse_type == "FP" + assert scenario.pulses[0].nb_pulses == 2 + assert scenario.pulses[0].ramp_up == 0.1 + assert scenario.pulses[0].steady_state == 0.2 + assert scenario.pulses[0].ramp_down == 0.3 + assert scenario.pulses[0].waiting == 0.4 + + assert scenario.pulses[1].pulse_type == "ICWC" + assert scenario.pulses[1].nb_pulses == 3 + assert scenario.pulses[1].ramp_up == 0.5 + assert scenario.pulses[1].steady_state == 0.6 + assert scenario.pulses[1].ramp_down == 0.7 + assert scenario.pulses[1].waiting == 0.8 + + scenario.to_txt_file("test_scenario.txt") + scenario2 = Scenario.from_txt_file("test_scenario.txt") + + assert len(scenario2.pulses) == 2 + assert scenario2.pulses[0].pulse_type == "FP" + assert scenario2.pulses[0].nb_pulses == 2 + assert scenario2.pulses[0].ramp_up == 0.1 + assert scenario2.pulses[0].steady_state == 0.2 + assert scenario2.pulses[0].ramp_down == 0.3 + assert scenario2.pulses[0].waiting == 0.4 + + assert scenario2.pulses[1].pulse_type == "ICWC" + assert scenario2.pulses[1].nb_pulses == 3 + assert scenario2.pulses[1].ramp_up == 0.5 + assert scenario2.pulses[1].steady_state == 0.6 + assert scenario2.pulses[1].ramp_down == 0.7 + assert scenario2.pulses[1].waiting == 0.8 def test_maximum_time(): # BUILD - my_scenario = Scenario(scenario_path) + + pulse1 = Pulse( + pulse_type="FP", + nb_pulses=2, + ramp_up=455, + steady_state=455, + ramp_down=650, + waiting=1000, + ) + pulse2 = Pulse( + pulse_type="ICWC", + nb_pulses=2, + ramp_up=36, + steady_state=36, + ramp_down=180, + waiting=1000, + ) + my_scenario = Scenario([pulse1, pulse2]) + expected_maximum_time = 2 * (455 + 455 + 650 + 1000) + 2 * (36 + 36 + 180 + 1000) # RUN @@ -21,56 +129,53 @@ def test_maximum_time(): assert computed_maximum_time == expected_maximum_time -@pytest.mark.parametrize("t, expected_row", [(0, 0), (6000, 1), (1e5, ValueError)]) -def test_get_pulse_row(t, expected_row): - my_scenario = Scenario(scenario_path) - - if isinstance(expected_row, type) and issubclass(expected_row, Exception): - with pytest.raises(expected_row): - my_scenario.get_row(t=t) +pulse1 = Pulse( + pulse_type="FP", + nb_pulses=2, + ramp_up=455, + steady_state=455, + ramp_down=650, + waiting=1000, +) +pulse2 = Pulse( + pulse_type="ICWC", + nb_pulses=2, + ramp_up=36, + steady_state=36, + ramp_down=180, + waiting=1000, +) + + +@pytest.mark.parametrize( + "t, expected_pulse", + [(0, pulse1), (6000, pulse2), (1e5, None), (pulse1.nb_pulses * pulse1.total_duration, pulse2)], +) +def test_get_pulse(t, expected_pulse): + + my_scenario = Scenario([pulse1, pulse2]) + + if expected_pulse is None: + with pytest.raises(ValueError): + my_scenario.get_pulse(t=t) else: - pulse_row = my_scenario.get_row(t=t) - assert pulse_row == expected_row - - -def test_reading_a_file(): - my_scenario = Scenario(scenario_path) - - times = np.linspace(0, my_scenario.get_maximum_time(), 1000) - pulse_types = [] - for t in times: - pulse_type = my_scenario.get_pulse_type(t) - pulse_types.append(pulse_type) - - # color the line based on the pulse type - color = { - "FP": "red", - "ICWC": "blue", - "RISP": "green", - "GDC": "orange", - "BAKE": "purple", - } - - colors = [color[pulse_type] for pulse_type in pulse_types] - - for i in range(len(times) - 1): - plt.plot(times[i : i + 2], np.ones_like(times[i : i + 2]), c=colors[i]) - # plt.xscale("log") - # plt.show() + pulse = my_scenario.get_pulse(t=t) + print(pulse.pulse_type) + assert pulse == expected_pulse -@pytest.mark.parametrize("t, expected_row", [(100, 0)]) -def test_one_line_scenario(t, expected_row): - my_scenario = Scenario(one_line_scenario_path) +@pytest.mark.parametrize("t, expected_pulse", [(100, pulse1)]) +def test_one_pulse_scenario(t, expected_pulse): + my_scenario = Scenario([expected_pulse]) - pulse_row = my_scenario.get_row(t=t) + pulse = my_scenario.get_pulse(t=t) - assert pulse_row == expected_row + assert pulse == expected_pulse @pytest.mark.parametrize("row, expected_duration", [(0, 2560), (1, 1252)]) def test_get_pulse_duration(row, expected_duration): - my_scenario = Scenario(scenario_path) + my_scenario = Scenario([pulse1, pulse2]) duration = my_scenario.get_pulse_duration(row=row) @@ -79,7 +184,7 @@ def test_get_pulse_duration(row, expected_duration): @pytest.mark.parametrize("row, expected_duration", [(0, 1560), (1, 252)]) def test_get_pulse_duration_no_waiting(row, expected_duration): - my_scenario = Scenario(scenario_path) + my_scenario = Scenario([pulse1, pulse2]) duration = my_scenario.get_pulse_duration_no_waiting(row=row) @@ -88,8 +193,34 @@ def test_get_pulse_duration_no_waiting(row, expected_duration): @pytest.mark.parametrize("row, expected_time", [(0, 0.0), (1, 5120.0)]) def test_get_time_till_row(row, expected_time): - my_scenario = Scenario(scenario_path) + my_scenario = Scenario([pulse1, pulse2]) elapsed_time = my_scenario.get_time_till_row(row=row) assert elapsed_time == expected_time + + +def test_reading_a_file(): + my_scenario = Scenario([pulse1, pulse2]) + + times = np.linspace(0, my_scenario.get_maximum_time(), 1000, endpoint=False) + pulse_types = [] + for t in times: + pulse_type = my_scenario.get_pulse_type(t) + pulse_types.append(pulse_type) + + # color the line based on the pulse type + color = { + "FP": "red", + "ICWC": "blue", + "RISP": "green", + "GDC": "orange", + "BAKE": "purple", + } + + colors = [color[pulse_type] for pulse_type in pulse_types] + + for i in range(len(times) - 1): + plt.plot(times[i : i + 2], np.ones_like(times[i : i + 2]), c=colors[i]) + # plt.xscale("log") + # plt.show()