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