Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loop over all Butcher tables to test order #488

Merged
merged 6 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions doc/arkode/guide/source/ARKodeButcherTable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,14 @@ ARKodeButcherTable functions
+--------------------------------------------------+------------------------------------------------------------+
| :c:func:`ARKodeButcherTable_LoadERKByName()` | Retrieve a given explicit Butcher table by its unique name |
+--------------------------------------------------+------------------------------------------------------------+
| :c:func:`ARKodeButcherTable_ERKIDToName()` | Convert an explicit Butcher table ID to its name |
+--------------------------------------------------+------------------------------------------------------------+
| :c:func:`ARKodeButcherTable_LoadDIRK()` | Retrieve a given implicit Butcher table by its unique ID |
+--------------------------------------------------+------------------------------------------------------------+
| :c:func:`ARKodeButcherTable_LoadDIRKByName()` | Retrieve a given implicit Butcher table by its unique name |
+--------------------------------------------------+------------------------------------------------------------+
| :c:func:`ARKodeButcherTable_DIRKIDToName()` | Convert an implicit Butcher table ID to its name |
+--------------------------------------------------+------------------------------------------------------------+
| :c:func:`ARKodeButcherTable_Alloc()` | Allocate an empty Butcher table |
+--------------------------------------------------+------------------------------------------------------------+
| :c:func:`ARKodeButcherTable_Create()` | Create a new Butcher table |
Expand Down Expand Up @@ -138,6 +142,21 @@ ARKodeButcherTable functions
**Notes:**
This function is case sensitive.

.. c:function:: const char* ARKodeButcherTable_ERKIDToName(ARKODE_ERKTableID emethod)

Converts a specified explicit Butcher table ID to a string of the same name.
The prototype for this function, as well as the integer names for each
provided method, are defined in the header file
``arkode/arkode_butcher_erk.h``. For further information on these tables and
their corresponding identifiers, see :numref:`Butcher`.

**Arguments:**
* *emethod* -- integer input specifying the given Butcher table.

**Return value:**
* The name associated with *emethod*.
* ``NULL`` pointer if *emethod* was invalid.

.. c:function:: ARKodeButcherTable ARKodeButcherTable_LoadDIRK(ARKODE_DIRKTableID imethod)

Retrieves a specified diagonally-implicit Butcher table. The prototype for
Expand Down Expand Up @@ -172,6 +191,22 @@ ARKodeButcherTable functions
This function is case sensitive.


.. c:function:: const char* ARKodeButcherTable_DIRKIDToName(ARKODE_DIRKTableID imethod)

Converts a specified diagonally-implicit Butcher table ID to a string of the
same name. The prototype for this function, as well as the integer names for
each provided method, are defined in the header file
``arkode/arkode_butcher_dirk.h``. For further information on these tables
and their corresponding identifiers, see :numref:`Butcher`.

**Arguments:**
* *imethod* -- integer input specifying the given Butcher table.

**Return value:**
* The name associated with *imethod*.
* ``NULL`` pointer if *imethod* was invalid.


.. c:function:: ARKodeButcherTable ARKodeButcherTable_Alloc(int stages, sunbooleantype embedded)

Allocates an empty Butcher table.
Expand Down
3 changes: 3 additions & 0 deletions include/arkode/arkode_butcher_dirk.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ ARKodeButcherTable_LoadDIRK(ARKODE_DIRKTableID imethod);
SUNDIALS_EXPORT ARKodeButcherTable
ARKodeButcherTable_LoadDIRKByName(const char* imethod);

SUNDIALS_EXPORT const char* ARKodeButcherTable_DIRKIDToName(
ARKODE_DIRKTableID imethod);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 2 additions & 0 deletions include/arkode/arkode_butcher_erk.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ ARKodeButcherTable_LoadERK(ARKODE_ERKTableID emethod);
SUNDIALS_EXPORT ARKodeButcherTable
ARKodeButcherTable_LoadERKByName(const char* emethod);

SUNDIALS_EXPORT const char* ARKodeButcherTable_ERKIDToName(ARKODE_ERKTableID emethod);

#ifdef __cplusplus
}
#endif
Expand Down
22 changes: 22 additions & 0 deletions src/arkode/arkode_butcher_dirk.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,28 @@ ARKodeButcherTable ARKodeButcherTable_LoadDIRKByName(const char* imethod)
return ARKodeButcherTable_LoadDIRK(arkButcherTableDIRKNameToID(imethod));
}

/*---------------------------------------------------------------
Returns the string name for a pre-set DIRK method by its ID.

Input: imethod -- integer key for the desired method
---------------------------------------------------------------*/
const char* ARKodeButcherTable_DIRKIDToName(ARKODE_DIRKTableID imethod)
{
/* Use X-macro to test each method name */
switch (imethod)
{
#define ARK_BUTCHER_TABLE(name, coeff) \
case name: return #name;
#include "arkode_butcher_dirk.def"
#undef ARK_BUTCHER_TABLE

default:
arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__,
"Unknown Butcher table");
return NULL;
}
}

/*---------------------------------------------------------------
Returns Butcher table ID for pre-set DIRK methods.

Expand Down
24 changes: 23 additions & 1 deletion src/arkode/arkode_butcher_erk.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/*---------------------------------------------------------------
Returns Butcher table structure for pre-set Runge Kutta methods.

Input: emthod -- integer key for the desired method
Input: emethod -- integer key for the desired method
---------------------------------------------------------------*/
ARKodeButcherTable ARKodeButcherTable_LoadERK(ARKODE_ERKTableID emethod)
{
Expand Down Expand Up @@ -54,6 +54,28 @@ ARKodeButcherTable ARKodeButcherTable_LoadERKByName(const char* emethod)
return ARKodeButcherTable_LoadERK(arkButcherTableERKNameToID(emethod));
}

/*---------------------------------------------------------------
Returns the string name for a pre-set Runge Kutta method by its ID.

Input: emethod -- integer key for the desired method
---------------------------------------------------------------*/
const char* ARKodeButcherTable_ERKIDToName(ARKODE_ERKTableID emethod)
{
/* Use X-macro to test each method name */
switch (emethod)
{
#define ARK_BUTCHER_TABLE(name, coeff) \
case name: return #name;
#include "arkode_butcher_erk.def"
#undef ARK_BUTCHER_TABLE

default:
arkProcessError(NULL, ARK_ILL_INPUT, __LINE__, __func__, __FILE__,
"Unknown Butcher table");
return NULL;
}
}

/*---------------------------------------------------------------
Returns Butcher table ID for pre-set Runge Kutta methods.

Expand Down
2 changes: 1 addition & 1 deletion test/answers
101 changes: 36 additions & 65 deletions test/unit_tests/arkode/CXX_serial/ark_test_butcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,76 +21,45 @@
#include <arkode/arkode_butcher_erk.h>
#include <iostream>
#include <ostream>
#include <string>
#include <sundials/sundials_types.h>
#include <vector>

#include "arkode/arkode_impl.h"

struct ARK_Table
{
const char* const name;
const char* const erk_table;
const char* const dirk_table;
};

// Main Program
int main()
{
// set vectors of individual tables to test
std::vector<std::string> Tables_ERK =
{"ARKODE_HEUN_EULER_2_1_2", "ARKODE_ARK2_ERK_3_1_2",
"ARKODE_BOGACKI_SHAMPINE_4_2_3", "ARKODE_ARK324L2SA_ERK_4_2_3",
"ARKODE_ZONNEVELD_5_3_4", "ARKODE_ARK436L2SA_ERK_6_3_4",
"ARKODE_SAYFY_ABURUB_6_3_4", "ARKODE_CASH_KARP_6_4_5",
"ARKODE_FEHLBERG_6_4_5", "ARKODE_DORMAND_PRINCE_7_4_5",
"ARKODE_ARK548L2SA_ERK_8_4_5", "ARKODE_VERNER_8_5_6",
"ARKODE_FEHLBERG_13_7_8", "ARKODE_ARK437L2SA_ERK_7_3_4",
"ARKODE_ARK548L2SAb_ERK_8_4_5", "ARKODE_SOFRONIOU_SPALETTA_5_3_4",
"ARKODE_SHU_OSHER_3_2_3", "ARKODE_VERNER_9_5_6",
"ARKODE_VERNER_10_6_7", "ARKODE_VERNER_13_7_8",
"ARKODE_VERNER_16_8_9"};
std::vector<std::string> Tables_DIRK = {"ARKODE_SDIRK_2_1_2",
"ARKODE_ARK2_DIRK_3_1_2",
"ARKODE_BILLINGTON_3_3_2",
"ARKODE_TRBDF2_3_3_2",
"ARKODE_KVAERNO_4_2_3",
"ARKODE_ARK324L2SA_DIRK_4_2_3",
"ARKODE_CASH_5_2_4",
"ARKODE_CASH_5_3_4",
"ARKODE_SDIRK_5_3_4",
"ARKODE_KVAERNO_5_3_4",
"ARKODE_ARK436L2SA_DIRK_6_3_4",
"ARKODE_KVAERNO_7_4_5",
"ARKODE_ARK548L2SA_DIRK_8_4_5",
"ARKODE_ARK437L2SA_DIRK_7_3_4",
"ARKODE_ARK548L2SAb_DIRK_8_4_5",
"ARKODE_ESDIRK324L2SA_4_2_3",
"ARKODE_ESDIRK325L2SA_5_2_3",
"ARKODE_ESDIRK32I5L2SA_5_2_3",
"ARKODE_ESDIRK436L2SA_6_3_4",
"ARKODE_ESDIRK43I6L2SA_6_3_4",
"ARKODE_QESDIRK436L2SA_6_3_4",
"ARKODE_ESDIRK437L2SA_7_3_4",
"ARKODE_ESDIRK547L2SA_7_4_5",
"ARKODE_ESDIRK547L2SA2_7_4_5"};
std::vector<ARKODE_ERKTableID> Tables_ARK_ERK = {ARKODE_ARK2_ERK_3_1_2,
ARKODE_ARK324L2SA_ERK_4_2_3,
ARKODE_ARK436L2SA_ERK_6_3_4,
ARKODE_ARK437L2SA_ERK_7_3_4,
ARKODE_ARK548L2SA_ERK_8_4_5,
ARKODE_ARK548L2SAb_ERK_8_4_5};
std::vector<ARKODE_DIRKTableID> Tables_ARK_DIRK =
{ARKODE_ARK2_DIRK_3_1_2, ARKODE_ARK324L2SA_DIRK_4_2_3,
ARKODE_ARK436L2SA_DIRK_6_3_4, ARKODE_ARK437L2SA_DIRK_7_3_4,
ARKODE_ARK548L2SA_DIRK_8_4_5, ARKODE_ARK548L2SAb_DIRK_8_4_5};
std::vector<std::string> STables_ARK = {"ARKODE_ARK2_3_1_2",
"ARKODE_ARK324L2SA_4_2_3",
"ARKODE_ARK436L2SA_6_3_4",
"ARKODE_ARK437L2SA_7_3_4",
"ARKODE_ARK548L2SA_8_4_5",
"ARKODE_ARK548L2SAb_8_4_5"};
int numfails = 0;
std::vector<ARK_Table> ark_tables =
{{"ARKODE_ARK2_3_1_2", "ARKODE_ARK2_ERK_3_1_2", "ARKODE_ARK2_DIRK_3_1_2"},
{"ARKODE_ARK324L2SA_4_2_3", "ARKODE_ARK324L2SA_ERK_4_2_3",
"ARKODE_ARK324L2SA_DIRK_4_2_3"},
{"ARKODE_ARK436L2SA_6_3_4", "ARKODE_ARK436L2SA_ERK_6_3_4",
"ARKODE_ARK436L2SA_DIRK_6_3_4"},
{"ARKODE_ARK437L2SA_7_3_4", "ARKODE_ARK437L2SA_ERK_7_3_4",
"ARKODE_ARK437L2SA_DIRK_7_3_4"},
{"ARKODE_ARK548L2SA_8_4_5", "ARKODE_ARK548L2SA_ERK_8_4_5",
"ARKODE_ARK548L2SA_DIRK_8_4_5"},
{"ARKODE_ARK548L2SAb_8_4_5", "ARKODE_ARK548L2SAb_ERK_8_4_5",
"ARKODE_ARK548L2SAb_DIRK_8_4_5"}};
drreynolds marked this conversation as resolved.
Show resolved Hide resolved

int numfails = 0;

// loop over individual ERK tables
std::cout << "\nTesting individual ERK methods:\n\n";
for (std::string table : Tables_ERK)
for (int i = ARKODE_MIN_ERK_NUM; i <= ARKODE_MAX_ERK_NUM; i++)
{
std::cout << "Testing method " << table << ":";
ARKODE_ERKTableID id = static_cast<ARKODE_ERKTableID>(i);
std::cout << "Testing method " << ARKodeButcherTable_ERKIDToName(id) << ":";

// load Butcher table
ARKodeButcherTable B = ARKodeButcherTable_LoadERKByName(table.c_str());
ARKodeButcherTable B = ARKodeButcherTable_LoadERK(id);
if (B == NULL)
{
std::cout << " error retrieving table, aborting\n";
Expand Down Expand Up @@ -123,12 +92,13 @@ int main()

// loop over individual DIRK tables
std::cout << "\nTesting individual DIRK methods:\n\n";
for (std::string table : Tables_DIRK)
for (int i = ARKODE_MIN_DIRK_NUM; i <= ARKODE_MAX_DIRK_NUM; i++)
{
std::cout << "Testing method " << table << ":";
ARKODE_DIRKTableID id = static_cast<ARKODE_DIRKTableID>(i);
std::cout << "Testing method " << ARKodeButcherTable_DIRKIDToName(id) << ":";

// load Butcher table
ARKodeButcherTable B = ARKodeButcherTable_LoadDIRKByName(table.c_str());
ARKodeButcherTable B = ARKodeButcherTable_LoadDIRK(id);
if (B == NULL)
{
std::cout << " error retrieving table, aborting\n";
Expand Down Expand Up @@ -161,18 +131,19 @@ int main()

// loop over ARK pairs
std::cout << "\nTesting ARK pairs:\n\n";
for (size_t i = 0; i < Tables_ARK_ERK.size(); i++)
for (ARK_Table& ark_table : ark_tables)
{
std::cout << "Testing method " << STables_ARK[i] << ":";
std::cout << "Testing method " << ark_table.name << ":";

// load Butcher tables
ARKodeButcherTable Be = ARKodeButcherTable_LoadERK(Tables_ARK_ERK[i]);
ARKodeButcherTable Be = ARKodeButcherTable_LoadERKByName(ark_table.erk_table);
if (Be == NULL)
{
std::cout << " error retrieving explicit table, aborting\n";
return 1;
}
ARKodeButcherTable Bi = ARKodeButcherTable_LoadDIRK(Tables_ARK_DIRK[i]);
ARKodeButcherTable Bi =
ARKodeButcherTable_LoadDIRKByName(ark_table.dirk_table);
if (Bi == NULL)
{
std::cout << " error retrieving implicit table, aborting";
Expand Down
11 changes: 9 additions & 2 deletions test/unit_tests/arkode/CXX_serial/ark_test_butcher.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Testing individual ERK methods:

Testing method ARKODE_HEUN_EULER_2_1_2: table matches predicted method/embedding orders of 2/1
Testing method ARKODE_ARK2_ERK_3_1_2: table matches predicted method/embedding orders of 2/1
Testing method ARKODE_BOGACKI_SHAMPINE_4_2_3: table matches predicted method/embedding orders of 3/2
Testing method ARKODE_ARK324L2SA_ERK_4_2_3: table matches predicted method/embedding orders of 3/2
Testing method ARKODE_ZONNEVELD_5_3_4: table matches predicted method/embedding orders of 4/3
Expand All @@ -20,8 +19,10 @@ ARKodeButcherTable_CheckOrder:

embedding order >= 6; reverting to simplifying assumptions
embedding order = 6
Testing method ARKODE_KNOTH_WOLKE_3_3: table matches predicted method/embedding orders of 3/0
Testing method ARKODE_ARK437L2SA_ERK_7_3_4: table matches predicted method/embedding orders of 4/3
Testing method ARKODE_ARK548L2SAb_ERK_8_4_5: table matches predicted method/embedding orders of 5/4
Testing method ARKODE_ARK2_ERK_3_1_2: table matches predicted method/embedding orders of 2/1
Testing method ARKODE_SOFRONIOU_SPALETTA_5_3_4: table matches predicted method/embedding orders of 4/3
Testing method ARKODE_SHU_OSHER_3_2_3: table matches predicted method/embedding orders of 3/2
Testing method ARKODE_VERNER_9_5_6: table matches predicted method/embedding orders of 6/5
Expand All @@ -46,11 +47,13 @@ ARKodeButcherTable_CheckOrder:

embedding order >= 6; reverting to simplifying assumptions
embedding order = 6
Testing method ARKODE_FORWARD_EULER_1_1: table matches predicted method/embedding orders of 1/0
Testing method ARKODE_RALSTON_EULER_2_1_2: table matches predicted method/embedding orders of 2/1
Testing method ARKODE_EXPLICIT_MIDPOINT_EULER_2_1_2: table matches predicted method/embedding orders of 2/1

Testing individual DIRK methods:

Testing method ARKODE_SDIRK_2_1_2: table matches predicted method/embedding orders of 2/1
Testing method ARKODE_ARK2_DIRK_3_1_2: table matches predicted method/embedding orders of 2/1
Testing method ARKODE_BILLINGTON_3_3_2: table matches predicted method/embedding orders of 2/3
Testing method ARKODE_TRBDF2_3_3_2: table matches predicted method/embedding orders of 2/3
Testing method ARKODE_KVAERNO_4_2_3: table matches predicted method/embedding orders of 3/2
Expand All @@ -73,6 +76,10 @@ Testing method ARKODE_QESDIRK436L2SA_6_3_4: table matches predicted method/embe
Testing method ARKODE_ESDIRK437L2SA_7_3_4: table matches predicted method/embedding orders of 4/3
Testing method ARKODE_ESDIRK547L2SA_7_4_5: table matches predicted method/embedding orders of 5/4
Testing method ARKODE_ESDIRK547L2SA2_7_4_5: table matches predicted method/embedding orders of 5/4
Testing method ARKODE_ARK2_DIRK_3_1_2: table matches predicted method/embedding orders of 2/1
Testing method ARKODE_BACKWARD_EULER_1_1: table matches predicted method/embedding orders of 1/0
Testing method ARKODE_IMPLICIT_MIDPOINT_1_2: table matches predicted method/embedding orders of 2/0
Testing method ARKODE_IMPLICIT_TRAPEZOIDAL_2_2: table matches predicted method/embedding orders of 2/0

Testing ARK pairs:

Expand Down
Loading