bool isDIRKButcherTableau( const RKButcherTableauBase<Scalar>& rkbt ) { if (isEmptyRKButcherTableau(rkbt)) { return false; } typedef ScalarTraits<Scalar> ST; int numStages_local = rkbt.numStages(); const Teuchos::SerialDenseMatrix<int,Scalar> A_local = rkbt.A(); for (int i=0 ; i<numStages_local ; ++i) { for (int j=0 ; j<numStages_local ; ++j) { if ((j>i) && (A_local(i,j) != ST::zero())) { return false; } } } return true; }
bool isSDIRKButcherTableau( const RKButcherTableauBase<Scalar>& rkbt ) { if (isEmptyRKButcherTableau(rkbt)) { return false; } if (!isDIRKButcherTableau(rkbt)) { return false; } // Verify the diagonal entries are all equal. typedef ScalarTraits<Scalar> ST; int numStages_local = rkbt.numStages(); const Teuchos::SerialDenseMatrix<int,Scalar> A_local = rkbt.A(); Scalar val = A_local(0,0); for (int i=0 ; i<numStages_local ; ++i) { if (A_local(i,i) != val) { return false; } } return true; }
bool RKButcherTableauBase<Scalar>::operator== (const RKButcherTableauBase<Scalar>& rkbt) const { if (this->numStages() != rkbt.numStages()) { return false; } if (this->order() != rkbt.order()) { return false; } int N = rkbt.numStages(); // Check b and c first: const Teuchos::SerialDenseVector<int,Scalar> b_ = this->b(); const Teuchos::SerialDenseVector<int,Scalar> c_ = this->c(); const Teuchos::SerialDenseVector<int,Scalar> other_b = rkbt.b(); const Teuchos::SerialDenseVector<int,Scalar> other_c = rkbt.c(); for (int i=0 ; i<N ; ++i) { if (b_(i) != other_b(i)) { return false; } if (c_(i) != other_c(i)) { return false; } } // Then check A: const Teuchos::SerialDenseMatrix<int,Scalar>& A_ = this->A(); const Teuchos::SerialDenseMatrix<int,Scalar>& other_A = rkbt.A(); for (int i=0 ; i<N ; ++i) { for (int j=0 ; j<N ; ++j) { if (A_(i,j) != other_A(i,j)) { return false; } } } return true; }
bool isERKButcherTableau( const RKButcherTableauBase<Scalar>& rkbt) { if (isEmptyRKButcherTableau(rkbt)) { return false; } // Verify the diagonal is zero and the upper triangular part is zero typedef ScalarTraits<Scalar> ST; int numStages_local = rkbt.numStages(); const Teuchos::SerialDenseMatrix<int,Scalar> A_local = rkbt.A(); for (int i=0 ; i<numStages_local ; ++i) { for (int j=0 ; j<numStages_local ; ++j) { if ((j>=i) && ((A_local(i,j) != ST::zero()))) { return false; } } } const Teuchos::SerialDenseVector<int,Scalar> c_local = rkbt.c(); if( c_local(0) != ST::zero() ) { return false; } // 08/13/08 tscoffe: I'm not sure what else I can check for b & c... return true; }
bool isEmptyRKButcherTableau( const RKButcherTableauBase<Scalar>& rkbt ) { typedef ScalarTraits<Scalar> ST; // Check that numStages > 0 if (rkbt.numStages() == 0) { return true; } // Check that the b vector has _some_ non-zero entry int numNonZero = 0; int numStages_local = rkbt.numStages(); const Teuchos::SerialDenseVector<int,Scalar> b_local = rkbt.b(); for (int i=0 ; i<numStages_local ; ++i) { if (b_local(i) != ST::zero()) { numNonZero++; } } if (numNonZero == 0) { return true; } // There is no reason to check A and c because they can be zero and you're // producing an explicit method as long as b has something in it. return false; }
E_RKButcherTableauTypes determineRKBTType(const RKButcherTableauBase<Scalar>& rkbt) { if (isEmptyRKButcherTableau(rkbt)) { return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_INVALID; } if (isERKButcherTableau(rkbt)) { return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_ERK; } if (rkbt.numStages() == 1) { // In this case, its just an IRK method. return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_IRK; } if (isSDIRKButcherTableau(rkbt)) { return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_SDIRK; } if (isDIRKButcherTableau(rkbt)) { return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_DIRK; } if (isIRKButcherTableau(rkbt)) { return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_IRK; } return RYTHMOS_RK_BUTCHER_TABLEAU_TYPE_INVALID; }