30 #ifndef RYTHMOS_RK_BUTCHER_TABLEAU_HELPERS_HPP 
   31 #define RYTHMOS_RK_BUTCHER_TABLEAU_HELPERS_HPP 
   33 #include "Rythmos_Types.hpp" 
   35 #include "Rythmos_RKButcherTableauBase.hpp" 
   36 #include "Teuchos_Assert.hpp" 
   37 #include "Thyra_ProductVectorBase.hpp" 
   42 template<
class Scalar>
 
   43 void assembleIRKState(
 
   45   const Teuchos::SerialDenseMatrix<int,Scalar> &A_in,
 
   47   const Thyra::VectorBase<Scalar> &x_base,
 
   48   const Thyra::ProductVectorBase<Scalar> &x_stage_bar,
 
   49   Teuchos::Ptr<Thyra::VectorBase<Scalar> > x_out_ptr
 
   55   const int numStages_in = A_in.numRows();
 
   56   TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( stageIndex, 0, numStages_in );
 
   57   TEUCHOS_ASSERT_EQUALITY( A_in.numRows(), numStages_in );
 
   58   TEUCHOS_ASSERT_EQUALITY( A_in.numCols(), numStages_in );
 
   59   TEUCHOS_ASSERT_EQUALITY( x_stage_bar.productSpace()->numBlocks(), numStages_in );
 
   60   Thyra::VectorBase<Scalar>& x_out = *x_out_ptr;
 
   62   V_V( outArg(x_out), x_base );
 
   63   for ( 
int j = 0; j < numStages_in; ++j ) {
 
   64     Vp_StV( outArg(x_out), dt * A_in(stageIndex,j), *x_stage_bar.getVectorBlock(j) );
 
   71 template<
class Scalar>
 
   72 void assembleIRKSolution(
 
   73   const Teuchos::SerialDenseVector<int,Scalar> &b_in,
 
   75   const Thyra::VectorBase<Scalar> &x_base,
 
   76   const Thyra::ProductVectorBase<Scalar> &x_stage_bar,
 
   77   Teuchos::Ptr<Thyra::VectorBase<Scalar> > x_out_ptr
 
   83   const int numStages_in = b_in.length();
 
   84   TEUCHOS_ASSERT_EQUALITY( b_in.length(), numStages_in );
 
   85   TEUCHOS_ASSERT_EQUALITY( x_stage_bar.productSpace()->numBlocks(), numStages_in );
 
   86   Thyra::VectorBase<Scalar>& x_out = *x_out_ptr;
 
   88   V_V( outArg(x_out), x_base );
 
   89   for ( 
int j = 0; j < numStages_in; ++j ) {
 
   90     Vp_StV( outArg(x_out), dt * b_in(j), *x_stage_bar.getVectorBlock(j) );
 
   96 template<
class Scalar>
 
   97 void assembleERKState(
 
   99   const Teuchos::SerialDenseMatrix<int,Scalar> &A_in,
 
  101   const Thyra::VectorBase<Scalar> &x_base,
 
  102   const Thyra::VectorBase<Scalar> &x_stage_bar,
 
  103   Teuchos::Ptr<Thyra::VectorBase<Scalar> > x_out_ptr
 
  106   TEUCHOS_TEST_FOR_EXCEPT(
true);
 
  110 template<
class Scalar>
 
  111 void assembleERKSolution(
 
  112   const Teuchos::SerialDenseVector<int,Scalar> &b_in,
 
  114   const Thyra::VectorBase<Scalar> &x_base,
 
  115   const Thyra::VectorBase<Scalar> &x_stage_bar,
 
  116   Teuchos::Ptr<Thyra::VectorBase<Scalar> > x_out_ptr
 
  119   TEUCHOS_TEST_FOR_EXCEPT(
true);
 
  122 template<
class Scalar>
 
  123 bool isEmptyRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt ) {
 
  124   typedef ScalarTraits<Scalar> ST;
 
  127   if (rkbt.numStages() == 0) {
 
  133   int numStages_local = rkbt.numStages();
 
  134   const Teuchos::SerialDenseVector<int,Scalar> b_local = rkbt.b();
 
  135   for (
int i=0 ; i<numStages_local ; ++i) {
 
  136     if (b_local(i) != ST::zero()) {
 
  140   if (numNonZero == 0) {
 
  149 template<
class Scalar>
 
  150 void assertNonEmptyRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  152   TEUCHOS_TEST_FOR_EXCEPTION( isEmptyRKButcherTableau(rkbt), std::logic_error,
 
  153       "Error, this RKButcherTableau is either empty or the b vector is all zeros!\n" 
  157 template<
class Scalar>
 
  158 bool isDIRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  160   if (isEmptyRKButcherTableau(rkbt)) {
 
  163   typedef ScalarTraits<Scalar> ST;
 
  164   int numStages_local = rkbt.numStages();
 
  165   const Teuchos::SerialDenseMatrix<int,Scalar> A_local = rkbt.A();
 
  166   for (
int i=0 ; i<numStages_local ; ++i) {
 
  167     for (
int j=0 ; j<numStages_local ; ++j) {
 
  168       if ((j>i) && (A_local(i,j) != ST::zero())) {
 
  176 template<
class Scalar>
 
  177 bool isIRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  179   if (isEmptyRKButcherTableau(rkbt)) {
 
  185 template<
class Scalar>
 
  186 void validateIRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  188   TEUCHOS_TEST_FOR_EXCEPTION( !isIRKButcherTableau(rkbt), std::logic_error,
 
  189     "Error!  This implicit RK Butcher Tableau is empty!\n" 
  193 template<
class Scalar>
 
  194 void validateDIRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  196   TEUCHOS_TEST_FOR_EXCEPTION( !isDIRKButcherTableau(rkbt), std::logic_error,
 
  197       "Error!  This Diagonal Implicit RK Butcher Tableau has non-zeros in the upper triangular part!\n" 
  201 template<
class Scalar>
 
  202 bool isSDIRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  204   if (isEmptyRKButcherTableau(rkbt)) {
 
  207   if (!isDIRKButcherTableau(rkbt)) {
 
  212   int numStages_local = rkbt.numStages();
 
  213   const Teuchos::SerialDenseMatrix<int,Scalar> A_local = rkbt.A();
 
  214   Scalar val = A_local(0,0);
 
  215   for (
int i=0 ; i<numStages_local ; ++i) {
 
  216     if (A_local(i,i) != val) {
 
  223 template<
class Scalar>
 
  224 void validateSDIRKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  226   TEUCHOS_TEST_FOR_EXCEPTION( !isSDIRKButcherTableau(rkbt), std::logic_error,
 
  227       "Error!  This Singly Diagonal Implicit RK Butcher Tableau does not have equal diagonal entries!\n" 
  231 template<
class Scalar>
 
  232 bool isERKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt)
 
  234   if (isEmptyRKButcherTableau(rkbt)) {
 
  238   typedef ScalarTraits<Scalar> ST;
 
  239   int numStages_local = rkbt.numStages();
 
  240   const Teuchos::SerialDenseMatrix<int,Scalar> A_local = rkbt.A();
 
  241   for (
int i=0 ; i<numStages_local ; ++i) {
 
  242     for (
int j=0 ; j<numStages_local ; ++j) {
 
  243       if ((j>=i) && ((A_local(i,j) != ST::zero()))) {
 
  248   const Teuchos::SerialDenseVector<int,Scalar> c_local = rkbt.c();
 
  249   if( c_local(0) != ST::zero() ) {
 
  258 template<
class Scalar>
 
  259 void validateERKButcherTableau( 
const RKButcherTableauBase<Scalar>& rkbt )
 
  261   TEUCHOS_TEST_FOR_EXCEPTION( !isERKButcherTableau(rkbt), std::logic_error,
 
  262       "Error!  This ERK Butcher Tableau is not lower triangular or c(0) is not zero!\n" 
  328 enum E_RKButcherTableauTypes {
 
  329   RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_INVALID,
 
  330   RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_ERK,
 
  331   RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_IRK,
 
  332   RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_DIRK,
 
  333   RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_SDIRK
 
  336 template<
class Scalar>
 
  337 E_RKButcherTableauTypes determineRKBTType(
const RKButcherTableauBase<Scalar>& rkbt) {
 
  338   if (isEmptyRKButcherTableau(rkbt)) {
 
  339     return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_INVALID;
 
  341   if (isERKButcherTableau(rkbt)) {
 
  342     return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_ERK;
 
  344   if (rkbt.numStages() == 1) {
 
  346     return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_IRK;
 
  348   if (isSDIRKButcherTableau(rkbt)) {
 
  349     return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_SDIRK;
 
  351   if (isDIRKButcherTableau(rkbt)) {
 
  352     return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_DIRK;
 
  354   if (isIRKButcherTableau(rkbt)) {
 
  355     return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_IRK;
 
  357   return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_INVALID;
 
  365 #endif // RYTHMOS_RK_BUTCHER_TABLEAU_HELPERS_HPP