Loading...

Searching...

No Matches

How to add a test case to Notus test case bank

The following guidelines will help you to add a test case to Notus test case bank.

A Notus test case is based on a *NTS* file and, eventually, some Fortran routines that compute initialization, boundary conditions, post-processing, etc. that cannot be done within the *NTS* file. Solution of a test case is also checked automatically at each release of the code by running the validation script. Finally, documentation should be written.

The next sections helps to realize these points.

Test case are separated into **verification** and **validation** test cases:

- The verification topic provides a set of test cases that aim to verify the base numerical methods. Precise convergence is verified, symmetry is tested. It is mainly a mathematical and computer work.
- The validation topic provides a set of test cases that aim to validate the usability of the code on typical, advanced and well documented physical cases taken from the literature. They can be used to compare results obtained with other CFD codes.

So, you have to put your *NTS* file in *test_cases/verification* or *test_cases.validation* directory.

Within each directory, you will find subdirectories where you can copy your file (or create a new category if necessary). For instance:

$ ls verification/ cell_advection_schemes laplacian linear_system_test navier phase_advection species_transport surface_tension $ ls validation/ free_convection laminar_flows mixed_convection multiphase thermosolutal turbulent_flow

We will name *your_test_case_category* this directory.

For more clarity, make sure that your *NTS* file has the suffix *_2D* or *_3D* before the *NTS* extension.

The test case should be validated precisely against exact solution, numerical solution or experimental data. Once this work is done, the associated documentation that presents the test case and the obtained solutions are written in a *doc.f90* file. This file is put in *src/notus/test_cases/your_test_case_category/your_test_case_directory*, where *your_test_case_directory* matches the *NTS* file without the extension.

For each equation solved, a reference solution can be obtained during the validation process of the test case (the mean velocity magnitude, the mean temperature, the mean species concentration, and/or the mean volume). These reference values, as well as a tolerance value, are entered in the *NTS* file in the *post_processing* block:

post_processing { validation { tolerance 1.d-13; reference_mean_temperature 2.999999999997118E+02; reference_mean_velocity_magnitude 3.7921755054867766E-03; reference_mean_volume_fraction 3.7921755054867766E-03; reference_mean_concentration 3.7921755054867766E-03; } }

After its creation, a new test case is nowhere to be listed. Indeed, the script will determine by itself the test cases required for the execution of the process chosen by the user (**Validation** or **Run**). At each new execution of the code, the solution is checked against the referenced one, and the test case is validated if the error is below the tolerance value.

Sometimes, you may want to execute more than a specific case determined by a specific set of parameters. Indeed, you may have to deal with variables that can take several values. All of these cases can be executed during the same process if variables are defined with the following syntax, where values_list can be any list generator of Python:

# @PARAMETER variable_type variable_name values_list

You can even filter the values taken by the variable:

# @PARAMETER integer variable [n for n in range(10) if n%2 == 0]

This syntax will return a list of integers between 0 and 9 where all odd numbers have been removed.

Notus will create as many jobs as there are possible combinations of the values taken by the variables. For instance:

# @PARAMETER integer dimension [1,2] # @PARAMETER string advection_scheme ['upwind_o1','weno5']

Notus will treat all the following cases: dimension = 1 and advection_scheme = 'upwind_o1', dimension = 1 and advection_scheme = 'weno5', dimension = 2 and advection_scheme = 'upwind_o1' and dimension = 2 and advection_scheme = 'weno5'.

If you want to use several solvers, values_list needs to be replaced since the list of all the solvers available will be automatically determined by the script.

# @PARAMETER string solver_name @SOLVER

Of course, the code can still be executed with the parameters defined at the beginning of the *NTS* file. The argument *- f* must be used in the command line to execute all cases. For further information, see run notus guide.

The number of MPI processors in *Validation Mode* is determined at the beginning of every *NTS*, regardless of the dimension of the case. The syntax is similar to the one used to define parameters :

# @MPI_PROCS integer

where *integer* is the number of MPI processors required.

To realise a convergence test case you have to put additionnal information into the *NTS* file:

# @CONVERGENCE [time|space] # @TIME_STEP float # @FINAL_TIME float # @STEPS int # @MESH int int [int] # @GEOMETRIC_FACTOR int

With this information, you can test spacial or time convergence. For instance:

# @CONVERGENCE time # @TIME_STEP 1.5 # @FINAL_TIME 4.0 # @STEPS 3 # @GEOMETRIC_FACTOR 2

Or for a spacial convergence:

# @CONVERGENCE space # @MESH 10 10 # @STEPS 3 # @GEOMETRIC_FACTOR 2

If you realize a time convergence, you will have to replace the time step value by `TIME_STEP`

in the nts file. As well for the final time value, that has to be replaced by `FINAL_TIME`

. For a space convergence, you will have to put `N_CELLS_X`

, `N_CELLS_Y`

(and `N_CELLS_Z`

if there are 3 dimensions) for the number of cells in the x, y (and z) direction.

The `# @MESH`

option is specific to spacial convergence. It has no impact on time convergence. As well, `# @TIME_STEP`

and `# @FINAL_TIME`

are specific to the time convergence.

You will also have to put a `validation`

block in the `post_processing`

block in the *NTS* file to choose to chose which output value will be taken for the convergence study. For more information, see post_processing in the [nts language documentation] (User Interface).

To add a scalability test case, it is the same principle. You have to put information about the scalability study into the nts file. You can set the following parameters:

# @SCALABILITY [weak|strong|strong_node] # @PROGRESSION [arithmetic|geometric|custom] int [int ...] # @MPI_PROCS_PER_NODE int # @TIME_ITERATIONS int # @DIMENSION int # @THREADS int [int ...] # @MESH int int [int] # @CELLS_PER_CORE int

The option `# @PROGRESSION`

indicates the series of number of nodes you want to do the scalability test. For instance, if you want to compute for 1, 2, 5, 10 nodes, you can use the command:

# @PROGRESSION custom 1 2 5 10

To make an arithmetic progression \( \left\{ u_n = u_0 + nr~|~\forall n<N \right\} \) you will have to indicate the initial term \( u_0 \), the common difference of successive members *r* and the number of terms *N* after the word arithemetic:<>>

# @PROGRESSION arithmetic u0 r n

It is also possible to make a geometric progression following the same principle. To make a geometric progression \( \left\{ u_n = u_0r^n~|~\forall n<N \right\} \), you will have to indicate the initial term \( u_0 \), the common ratio *r* and the number of terms *N* after the word geometric:<>>

# @PROGRESSION geometric u0 r n

For instance, if you want the progression \( u_n = 1 + 2n \), with 5 terms, you will use the command:

# @PROGRESSION arithmetic 1 2 5

You can set the initial mesh using `# @MESH`

or `# @CELLS_PER_CORE`

. You need to replace the number of cells in the x, y (and z) direction by `N_CELLS_X`

, `N_CELLS_Y`

(and `N_CELLS_Z`

if there are 3 dimensions). With the `# @MESH`

option, you set the number of cells for each directionxs. Withxe the `# @CELLS_PER_CORE`

, you set the number of cells per core, and with the total number of cells, the script will generate a mesh with the same number of cells for each direction.

For instance, for 2 cores, in 2D, you can use `# @MESH 10 10`

or `# @CELLS_PER_CORE 50`

to generate the same mesh.

You can precise the number of threads you want. If you put several number of threads, like `# @THREADS 1 2`

, the script will launch a study for 1 thread, and then a study on 2 threads.

By default, if you do not precise the number of threads, the computation will use only 1 threads.

To lead scalability studies, some options are necessary:

# @MPI_PROCS_PER_NODE # @MESH or # @CELLS_PER_CORE # @DIMENSION # @PROGRESSION

# @MPI_PROCS_PER_NODE # @DIMENSION # @PROGRESSION

# @DIMENSION # @PROGRESSION

There is an example of the option you can write in the nts file to create a weak scalability:

# @SCALABILITY weak # @DIMENSION 2 # @THREADS 1 # @MPI_PROCS_PER_NODE 16 # @PROGRESSION geometric 1 2 4 # @CELLS_PER_CORE 5000

This options will generate a weak study on 1, 2, 4, 8 nodes, with a mesh of 282x282.

If the test case needs special Fortran routines, the execution mode switches from the default mode (that passes through user routines) to the *test_case* mode that passes through specific routines associated to the test case that is run. This is done thanks a special keyword that is added to the *NTS* file.

First, add your test case in the Notus test case enumeration that needs specific Fortran routines, in the `src/notus/test_cases/enum.f90`

file:

enumerator :: test_case_your_test_case_name

In the User Interface part of the code, *src/notus/ui/keywords.f90* file, add an enumerator beginning with `kw_tc_`

:

! Test case keywords enumerator :: kw_tc_your_test_case_name

Then, in the same file, in subroutine `ui_keyword_list_initialize`

, add the keyword into the keyword list:

ui_keywords(kw_tc_your_test_case_name )%name = "tc_your_test_case_name"

Then, in *src/notus/ui/tree/system/block_reader.f90* file, in the `select case(tok_test_casekeyword_id)`

section, add your test case:

case(kw_tc_your_test_case) test_case = test_case_your_test_case

Now, compile again the code !

Specific routines must be separated into several ones which names are:

*prepation.f90*: for special initialization, boundary condition, etc.*new_iteration.f90*: called in the time loop before the resolution of the equation (for time dependent boundary conditions, source terms, etc.)*reference_solution.f90*: to compute the reference solution*post_process.f90*: for specific post-processing

These routine are put in the *src/notus/test_cases/your_test_case_category/your_test_case_directory* directory.

The switch during the execution from a set of routines associated to one test case to another is done in the *src/notus/test_cases* directory in which you have to modify *compute_reference_solution.f90*, *tc_prepare_next_iteration.f90*, *tc_post_process.f90* and *tc_prepare.f90* routines.

Now, compile again the code, and your test case should be added !