Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75387 - sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples
From: cppljevans_at_[hidden]
Date: 2011-11-07 10:12:05


Author: cppljevans
Date: 2011-11-07 10:12:03 EST (Mon, 07 Nov 2011)
New Revision: 75387
URL: http://svn.boost.org/trac/boost/changeset/75387

Log:
After making changes to accommodate mv of solve_tridiag.hpp.
Also, *_pde.cpp now reads grid from file instead of using hardcoded grid.

Text files modified:
   sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/array_dyn.diff_pde.cpp | 597 ++++++++++++++++++++++++---------------
   sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/index_stack_length_stride_crtp~demo.cpp | 17
   sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/solve_tridiag.cpp | 8
   3 files changed, 377 insertions(+), 245 deletions(-)

Modified: sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/array_dyn.diff_pde.cpp
==============================================================================
--- sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/array_dyn.diff_pde.cpp (original)
+++ sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/array_dyn.diff_pde.cpp 2011-11-07 10:12:03 EST (Mon, 07 Nov 2011)
@@ -3,11 +3,11 @@
 // numerical solution of diffusion differential equation.
 //References:
 //==============================
-// The "Alternating Directions Explicit(ADE)" method is
-// described here:
 /*
   [DuffyAde2011]
- http://www.datasimfinancial.com/forum/download.php?id=351
+ http://www.datasimfinancial.com/forum/files/pdeade_344.pdf
+ downloadable from:
+ http://www.datasimfinancial.com/forum/viewtopic.php?t=289
  */
 //==============================
 /*
@@ -18,7 +18,6 @@
     John Wiley & Sons, Ltd(2006)
  */
 //==============================
-// The limits on del_t are from page 3 of:
 /*
   [Hor05]
     http://www.cosy.sbg.ac.at/events/parnum05/book/horak1.pdf
@@ -33,7 +32,7 @@
 #include <iomanip>
 #include <initializer_list>
 #include <deque>
-#include <boost/array_stepper/solve_tridiag.hpp>
+#include <boost/array_stepper/numeric/solve_tridiag.hpp>
 
     typedef
   double
@@ -207,7 +206,7 @@
        */
     ;
     grid_axis_size_bounds
- ( unsigned a_size=2
+ ( unsigned a_size=3
     , value_t a_lower=0.1
     , value_t a_upper=1.0
     )
@@ -230,16 +229,34 @@
         <<"( size="<<a.size
         <<", lower="<<a.lower
         <<", upper="<<a.upper
- <<"}";
+ <<")\n";
       return sout;
   }
   
+ template
+ < typename Value
+ >
+ std::istream&
+operator>>
+ ( std::istream& sinp
+ , grid_axis_size_bounds<Value>& a
+ )
+ {
+ sinp
+ >>a.size
+ >>a.lower
+ >>a.upper
+ ;
+ return sinp;
+ }
+
 
   template
   < typename Value
>
 struct grid_axis_points
 {
+ //#define GRID_AXIS_POINTS_TRACE_DEL
         typedef
       Value
     value_t
@@ -294,6 +311,9 @@
     del_put(value_t a_del)
       {
           my_del=a_del;
+ #ifdef GRID_AXIS_POINTS_TRACE_DEL
+ std::cout<<"del_put="<<my_del<<"\n";
+ #endif
       }
       grid_axis_points const&
     operator=
@@ -334,8 +354,17 @@
       {
             value_t
           result=(a_upper-my_lower)/value_t(my_size-1);
+ #ifdef GRID_AXIS_POINTS_TRACE_DEL
+ std::cout
+ <<"mk_del:a_upper="<<a_upper
+ <<":my_lower="<<my_lower
+ <<":my_size="<<my_size
+ <<":result="<<result
+ <<"\n";
+ #endif
           return result;
       }
+ #undef GRID_AXIS_POINTS_TRACE_DEL
 };
   
   template
@@ -348,10 +377,21 @@
   )
   {
       sout
- <<"( size="<<a.size()
+ <<"grid_axis_points"
+ <<"{ size="<<a.size()
         <<", lower="<<a.lower()
         <<", del="<<a.del()
- <<"}";
+ ;
+ #if 0
+ sout<<", points={ ";
+ for(unsigned i=0; i<a.size(); ++i)
+ {
+ if(0<i)sout<<", ";
+ sout<<a[i];
+ }
+ sout<<"} ";
+ #endif
+ sout<<"}";
       return sout;
   }
   
@@ -384,15 +424,33 @@
             )
           {
               my_axes[i]=a_iter[i];
+ auto const axis_size=my_axes[i].size();
+ if(axis_size<3)
+ {
+ //In this case, either a boundary is missing (axis_size<2)
+ //or there are no interior points (axis_size==2), and if
+ //there are no interior points, then all points are set by
+ //boundary conditions; hence, there's no need to solve the
+ //pde.
+ std::cerr<<"space axes mus have size>2. space axis "<<i<<" size="<<axis_size<<".\n";
+ std::exit(1);
+ }
               if(my_axes[i].del()<del_s_min)
                   del_s_min=my_axes[i].del();
           }
             value_t
           del_t=(del_s_min*del_s_min)/(4.0*diffusivity)
- //time increment, from page 6 of [Hor05].
+ //time increment, from page 6(numbered as 52)
+ //of [Hor05]
             //*except* min del_s is chosen instead
             //of a single space delta since there's a
             //n-1 space deltas.
+ //If diffusivity==1.0, this is same as the constraint:
+ // k/h^2 <= 1/4
+ //on page 203 of [DuffyFdm2006]. Of course this is
+ //for the explicit Euler scheme shown in equation(18.30)
+ //on previous page and is probably more stringent
+ //than it needs to be for some other FDM schems.
             ;
           del_t/=10.0
             //reduce for extra insurance.
@@ -419,7 +477,11 @@
     grid_axes_size_bounds_t
       ;
         typedef
- std::vector<grid_axis_points<value_t> >
+ grid_axis_points<value_t>
+ grid_axis_points_t
+ ;
+ typedef
+ std::vector<grid_axis_points_t>
     grid_axes_points_t
       ;
     grid_axes_diff
@@ -474,13 +536,7 @@
       {
           if(0<i)sout<<", ";
           auto const&axis=axes[i];
- sout<<"{ ";
- for(unsigned j=0; j<axis.size(); ++j)
- {
- if(0<j)sout<<", ";
- sout<<axis[j];
- }
- sout<<"}\n";
+ sout<<"axis["<<i<<"]="<<axis<<"\n";
       }
       sout<<"}\n";
       return sout;
@@ -643,7 +699,7 @@
       void
     boundary_conditions( value_t t_val, arr_data_iter_t& u_iter, istk_indices_t& s_iter)
       {
- #define TRACE_BOUNDARY_CONDITIONS
+ //#define TRACE_BOUNDARY_CONDITIONS
               typedef
             typename istk_indices_t::axis_t
           axis_t
@@ -817,7 +873,9 @@
         
         std::ios_base::fmtflags fmtflags0=std::cout.flags();
         unsigned precision0=std::cout.precision();
+ #if 0
         std::cout<<"estim_exact=\n"<<estim_exact_arr<<"\n.";
+ #endif
         std::cout<<"hot_spots=\n";
         std::cout<<"{ ";
         for( int i_time=0; i_time<t_space; ++i_time)
@@ -853,7 +911,9 @@
>
 struct diff_alt_dir_explicit
   /**@brief
- * Solves diffusion eq with method described in [DuffyAde2011].
+ * Solves diffusion eq with the
+ * Alternating Directions Explicit(ADE)
+ * method described in [DuffyAde2011].
    */
 ;
   template
@@ -949,6 +1009,11 @@
       #ifdef TRACE_SOLN_DIFF_EQ
         ::boost::trace_scope ts("diff_alt_dir_explicit::solve()");
       #endif
+ value_t const
+ del_t=this->axes()[0].del()
+ //the delta t in equations(9,10,11) of
+ //[DuffyAde2011].
+ ;
           std::vector<value_t>
         t_div_s2(s_rank)
           //These are the lambda's in equation(11) of [DuffyAde2011]
@@ -957,14 +1022,18 @@
           ;
           value_t
         sum_tds=0.0
- //This is the sigma of equation(11) of [DuffyAde2011]
+ //This is the lower case sigma of equation(11) of [DuffyAde2011]
           ;
         for( unsigned s_axis=0; s_axis<s_rank; ++s_axis)
         {
- value_t del_s_axis=this->axes()[s_axis+1].del();
+ value_t
+ del_s_axis=this->axes()[s_axis+1].del()
+ //This is h[j], where j corresponds to s_axis,
+ //in [DuffyAde2011], equation(11).
+ ;
             t_div_s2[s_axis]
- = ( this->axes()[0].del()
- * this->diffusivity //in [DuffyAde201], this was 1.0
+ = ( del_t
+ * this->diffusivity //in [DuffyAde2011], this was 1.0
                 )/
                 ( del_s_axis
                 * del_s_axis
@@ -984,25 +1053,13 @@
           value_t const
         one_minus_sum_tds=1.0-sum_tds
           ;
- value_t const
- one_minus_div_one_plus_sum_tds=one_minus_sum_tds/one_plus_sum_tds
- ;
       #ifdef TRACE_SOLN_DIFF_EQ
         std::cout
           <<"sum_tds="<<sum_tds<<"\n"
           <<"one_plus_sum_tds="<<one_plus_sum_tds<<"\n"
           <<"one_minus_sum_tds="<<one_minus_sum_tds<<"\n"
- <<"one_minus_div_one_plus_sum_tds="<<one_minus_div_one_plus_sum_tds<<"\n"
           ;
       #endif
- std::vector<value_t>
- t_div_s2_div_one_plus_sum_tds(s_rank)
- ;
- for( unsigned s_axis=0; s_axis<s_rank; ++s_axis)
- {
- t_div_s2_div_one_plus_sum_tds[s_axis]
- =t_div_s2[s_axis]/one_plus_sum_tds;
- }
           unsigned const
         n_time=this->axes()[0].size();
         for
@@ -1097,16 +1154,22 @@
                     incdec_v=incdecs[i_sweep];
                       array_t&
                     sweep_i_arr=sweeps[i_sweep];
- std::copy_n
- ( ut_now_iter-u.offset()
- , sweep_i_arr.data().size()
- , sweep_i_arr.data().begin()
- );
+ {//MAINTENANCE_NOTE:2011-11-03
+ // This really needs to only copy
+ // boundary values; however, since there's
+ // (as yet) no function to do just that,
+ // copy all the data.
+ std::copy_n
+ ( ut_now_iter-u.offset()
+ , sweep_i_arr.data().size()
+ , sweep_i_arr.data().begin()
+ );
+ }
                       arr_data_iter_t
                     sweep_i_iter=sweep_i_arr.data().begin()+sweep_i_arr.offset();
                     enum
- { u_stride_index
- , s_stride_index
+ { old_stride_index
+ , sweep_stride_index
                     };
                       unsigned const
                     stride_indices[sweeps_size]=
@@ -1126,26 +1189,36 @@
                       #ifdef TRACE_UPDATE_INNER_MESH
                         ::boost::trace_scope ts("s_node");
                         std::cout<<"s_node="<<s_node<<"\n";
- std::cout<<"space_istk_is="<<space_istk_is<<"\n";
                       #endif
                           auto const
                         space_offset=space_istk_is.offset_space_val();
                           arr_data_iter_t
- uts_node_iter=ut_now_iter+space_offset;
+ old_iter=ut_now_iter+space_offset;
                           arr_data_iter_t
- sweep_node_iter=sweep_i_iter+space_offset;
+ sweep_iter=sweep_i_iter+space_offset;
                           value_t&
- sweep_node0=sweep_node_iter[0]
+ sweep0=sweep_iter[0]
                           //The lhs of equation(9 or 10) of [DuffyAde2011]
                           //divided by (1+lower case sigma).
- ;
- sweep_node0=uts_node_iter[0]*one_minus_div_one_plus_sum_tds
+ ;
+ sweep0
+ = one_minus_sum_tds
+ * old_iter[0]
                           //The rhs of this assignment is
                           //1st term on rhs of equation(9 or 10)of [DuffyAde2011]
- //divided by (1+lower case sigma)[in [DuffyAde2011]]
- //[or one_plus_sum_tds here].
- ;
- { //add to sweep_node0, the rhs of equation( 9 or 10)
+ ;
+ #ifdef TRACE_UPDATE_INNER_MESH
+ std::cout
+ <<":old_iter[0]="<<old_iter[0]
+ <<":sweep0=(1-sigma)*old_iter[0]="<<sweep0
+ <<":sweep0 indices="
+ <<sweep_i_arr.indices_at_offset
+ ( space_offset
+ )
+ <<"\n"
+ ;
+ #endif
+ { //add to sweep0, the rhs of equation( 9 or 10)
                           //except for 1st term.
                             for
                               ( unsigned s_axis=0
@@ -1165,27 +1238,28 @@
                                   , -stride_v
                                   };
                                   stride_t const
- stride_u=stride_plus_minus[stride_indices[u_stride_index]]
+ old_stride_value=stride_plus_minus[stride_indices[old_stride_index]]
                                   ;
                                   value_t
- uts_node_stride=
- uts_node_iter
- [ stride_u
+ old_stride_iter=
+ old_iter
+ [ old_stride_value
                                     // ==+stride_v if i_sweep==0
                                     // ==-stride_v if i_sweep==1
                                   ]
                                   //this expresssion corresponds to
                                   //the U(if i_sweep==0) or V(if i_sweep==1)
- //with n superscript of rhs of equation(9 or 10)
+ //with n superscript of rhs of
+ //equation(9, if i_sweep==0 or 10, if i_sweep=1)
                                   //in [DuffyAde2011].
                                   ;
                                   stride_t const
- stride_s=stride_plus_minus[stride_indices[s_stride_index]]
+ sweep_stride_value=stride_plus_minus[stride_indices[sweep_stride_index]]
                                   ;
                                   value_t
- sweep_node_stride=
- sweep_node_iter
- [ stride_s
+ sweep_stride_iter=
+ sweep_iter
+ [ sweep_stride_value
                                     // ==-stride_v if i_sweep==0
                                     // ==+stride_v if i_sweep==1
                                   ]
@@ -1195,32 +1269,47 @@
                                   //in [DuffyAde2011].
                                   ;
                                   value_t
- sum_uts_sweep_node=uts_node_stride+sweep_node_stride;
- sweep_node0+=
- t_div_s2_div_one_plus_sum_tds[s_axis]
- * sum_uts_sweep_node
- //This is one of the terms on rhs of equation(9)
+ sum_old_sweep=old_stride_iter+sweep_stride_iter;
+ sweep0
+ += t_div_s2[s_axis]
+ * sum_old_sweep
+ //This is one of the terms on rhs of equation(9 or 10)
                                   //of [DuffyAde2011] which are multiplied
                                   //by one of the lambda's(s_axis corresponds to
- //the lambda subscript in equation(9))
- //then divided by (1+lower case sigma)
+ //the lambda subscript in equation(9 or 10)).
                                   ;
                               #ifdef TRACE_UPDATE_INNER_MESH
                                 std::cout
- <<":stride_index_s="<<stride_indices[s_stride_index]
- <<":stride_u="<<stride_u
- <<":stride_s="<<stride_s
- <<":uts_node_stride="<<uts_node_stride
- <<":sweep_node_stride="<<sweep_node_stride
- <<":indices_s="
- <<sweep_i_arr.indexs_at_offset
+ <<":old_stride_iter="<<old_stride_iter
+ <<":sweep_stride_iter="<<sweep_stride_iter
+ <<":old_indices="
+ <<sweep_i_arr.indices_at_offset
                                     ( space_offset
- + stride_s
+ + old_stride_value
+ )
+ <<":sweep_indices="
+ <<sweep_i_arr.indices_at_offset
+ ( space_offset
+ + sweep_stride_value
                                     )
                                   <<"\n";
                               #endif
                             }//for stride_iter_v
- } //add to sweep_node0
+ {//TODO: add forcing term here to sweep0.
+ //This is the del_t*F^(n+1)[i,j,k]
+ //in equations(9 and 10) of [DuffyAde2011].
+ }
+ sweep0/=one_plus_sum_tds
+ //divide by factor of U or V on lhs
+ //in equations(9 and 10) of [DuffyAde2011].
+ ;
+ #ifdef TRACE_UPDATE_INNER_MESH
+ std::cout
+ <<":sweep0/="<<sweep0
+ <<"\n"
+ ;
+ #endif
+ } //add to sweep0
                     }//for(s_node, for sweeps
                 }//for(i_sweep
                 for//each node in inner mesh, calculate next u value.
@@ -1259,15 +1348,13 @@
                     uts_nxt_node/=value_t(sweeps_size);//average sweeps
                   #if defined(TRACE_UPDATE_INNER_MESH) || 0
                     std::cout
- <<":exact="<<uts_nxt_node.exact
- <<":%err="<<uts_nxt_node.err_percent()
+ <<":uts_nxt_node(average_at_s_node="<<s_node<<")="<<uts_nxt_node
                       <<"\n";
                   #endif
                 }//for(s_node
               #undef TRACE_UPDATE_INNER_MESH
             } //update inner nodes in mesh
         }//for(i_time=...)
- std::cout<<"u["<<n_time<<"]=\n"<<u<<".\n";
       #undef TRACE_SOLN_DIFF_EQ
       #endif
     }
@@ -1275,12 +1362,13 @@
 #endif
 #define DIFF_ALT_DIR_IMPLICIT_INNOCENT
 #ifdef DIFF_ALT_DIR_IMPLICIT_INNOCENT
+#define TRACE_ALT_DIR_IMPLICIT_INNOCENT 1
   template
   < typename FunctionsDerived
>
 struct diff_alt_dir_implicit_innocent
   /**@brief
- * Solves diffusion eq with "innocent-looking" implicit method
+ * Solves diffusion eq with the "innocent-looking" implicit method
    * described in [DuffyFdm2006] in section 19.5 on page 217
    * in equations(19.34).
    */
@@ -1381,59 +1469,33 @@
           unsigned const
         s_rank=space_istk_is.rank();
         initial_conditions( u_iter, space_istk_is);
- #if 1
- //#define TRACE_SOLN_DIFF_EQ
- #ifdef TRACE_SOLN_DIFF_EQ
+ #define TRACE_SOLN_DIFF_EQ (1 && TRACE_ALT_DIR_IMPLICIT_INNOCENT)
+ #if TRACE_SOLN_DIFF_EQ
         ::boost::trace_scope ts("diff_alt_dir_implicit_innocent::solve()");
       #endif
+ typename super_t::grid_axes_points_t const&
+ grid_axes_points=this->axes();
+ typename super_t::grid_axis_points_t const&
+ time_axis=grid_axes_points[0];
           value_t const
- dt_div_s_rank
+ del_t_frac
           //time delta divided by space rank.
           //This is the k/3 (where s_rank replaces the 3)
           //in [DuffyFdm2006] equaiton(19.34).
- = this->axes()[0].del()/value_t(s_rank)
- ;
- typedef
- std::vector<value_t>
- del_s2_t
- ;
- struct
- del_s2_mk
- {
- typedef
- typename grid_axes_diff<value_t>::grid_axes_points_t
- axes_t
- ;
- static
- del_s2_t
- _
- ( axes_t const& a_axes
- )
- {
- auto const rank=a_axes.size();
- del_s2_t result(rank-1);
- for(unsigned s_axis=1; s_axis<rank; ++s_axis)
- {
- value_t del_axis=a_axes[s_axis].del();
- result[s_axis-1]=del_axis*del_axis;
- }
- return result;
- }
- };
- del_s2_t const
- del_s2_v
- = del_s2_mk::_( this->axes() )
- ;
+ = time_axis.del()/value_t(s_rank);
+ typename super_t::grid_axes_points_t
+ space_axes( grid_axes_points.begin()+1, grid_axes_points.end());
           value_t
- t_nxt=this->axes()[0][0];
- #ifdef TRACE_SOLN_DIFF_EQ
+ t_nxt=time_axis[0];
+ #if TRACE_SOLN_DIFF_EQ
         std::cout
- <<":dt_div_s_rank="<<dt_div_s_rank
+ <<":del_t_frac="<<del_t_frac
+ <<":space_axes(unrotated)="<<space_axes
           <<"\n"
           ;
       #endif
           unsigned const
- n_time=this->axes()[0].size();
+ n_time=time_axis.size();
         for
           ( unsigned i_time=0
           ; i_time<n_time-1
@@ -1445,12 +1507,12 @@
         {
               value_t
             t_now=t_nxt;
- t_nxt=this->axes()[0][i_time+1];
- #ifdef TRACE_SOLN_DIFF_EQ
+ t_nxt=time_axis[i_time+1];
+ #if TRACE_SOLN_DIFF_EQ
             ::boost::trace_scope ts("trace_soln_diff_eq");
- std::cout<<"i_time.{="<<i_time<<"\n";
- std::cout<<"t_now="<<t_now<<"\n";
- std::cout<<"u["<<i_time<<"]=\n"<<u<<".\n";
+ std::cout<<":i_time.{="<<i_time<<"\n";
+ std::cout<<":t_now="<<t_now<<"\n";
+ std::cout<<":u["<<i_time<<"]=\n"<<u<<".\n";
           #endif
               arr_data_iter_t
             ut_now_iter=u_iter+time_istk_is.offset_space_val()
@@ -1463,14 +1525,11 @@
             ut_nxt_iter=u_iter+time_istk_is.offset_space_val()
               //u at (i_time+1)-th time.
               ;
- auto const
- s_rank=space_istk_is.rank()
- ;
             {//EQUATIONS_19_34
              // This block implements equations(19.34) of
              // [DuffyFdm2006] for time step, i_time.
- #define TRACE_EQUATIONS_19_34
- #ifdef TRACE_EQUATIONS_19_34
+ #define TRACE_EQUATIONS_19_34 (1 && TRACE_ALT_DIR_IMPLICIT_INNOCENT)
+ #if TRACE_EQUATIONS_19_34
                 ::boost::trace_scope ts("EQUATIONS_19_34");
               #endif
                   std::vector<array_t>
@@ -1500,7 +1559,7 @@
                   //This will have its axes rotated during each
                   //iteration of the following loop so that
                   //solve_tridiag, which solves for the
- //last axis, will solve for each axes in
+ //last axis, will solve for each axes
                   //in turn.
                   ;
                 for
@@ -1510,12 +1569,14 @@
                   )
                 {
                     space_istk_rotated.rotate(1);
- #define TRACE_FRACTIONAL_STEPS
- #ifdef TRACE_FRACTIONAL_STEPS
+ std::rotate( space_axes.begin(), space_axes.begin()+1, space_axes.end());
+ #define TRACE_FRACTIONAL_STEPS (1 && TRACE_ALT_DIR_IMPLICIT_INNOCENT)
+ #if TRACE_FRACTIONAL_STEPS
                     ::boost::trace_scope ts("fractional step");
                     std::cout
                       <<":i_step="<<i_step
                       <<":rotation="<<space_istk_rotated.rotation()
+ <<":space_axes="<<space_axes
                       <<"\n";
                   #endif
                       array_t
@@ -1535,7 +1596,8 @@
                       //the current fractional step.
                       //IOW, the U on lhs of equations(19.41).
                       ;
- t_frac+=dt_div_s_rank;
+ t_frac+=del_t_frac;
+ #if 1
                     space_istk_is.axes_offsets_put(1,1);
                     space_istk_is.axis_offsets_put(i_step,0,0);
                     boundary_conditions_axis
@@ -1544,28 +1606,46 @@
                       , space_istk_is
                       , i_step
                       )
+ #else
+ boundary_conditions
+ ( t_frac
+ , rhs_iter
+ , space_istk_is
+ )
+ #endif
                       //This stores into rhs_iter i_step axis boundaries
                       //the rhs of equations(19.44) of [DuffyFdm2006].
                       ;
- #ifdef TRACE_FRACTIONAL_STEPS
+ #if TRACE_FRACTIONAL_STEPS
                     {
                         std::cout
- <<":t_frac="<<t_frac
+ <<":t_frac["<<i_time<<","<<(i_step+1)<<"]="<<t_frac<<"\n";
+ std::cout
                           <<":rhs["<<i_time<<","<<(i_step+1)<<"](after boundary_conditions)=\n"<<rhs
                           <<".\n";
                     }
                   #endif
                     {//interior_rhs
- //#define TRACE_INTERIOR_RHS
- #ifdef TRACE_INTERIOR_RHS
- ::boost::trace_scope
- ts("interior_rhs");
- #endif
                         space_istk_rotated.axes_offsets_put(1,1)
                           //restrict to interior nodes.
                           ;
                           auto const
                         s_space_inner=space_istk_rotated.space();
+ #define TRACE_INTERIOR_RHS (1 && TRACE_ALT_DIR_IMPLICIT_INNOCENT)
+ #if TRACE_INTERIOR_RHS
+ ::boost::trace_scope
+ ts("interior_rhs");
+ {
+ std::cout
+ <<":space_istk_rotated="<<space_istk_rotated<<"\n"
+ <<":s_space_inner="<<s_space_inner<<"\n"
+ <<":old_rotated["<<i_time<<","<<(i_step)<<"]=\n";
+ istk_indices_t space_istk_border(space_istk_rotated);
+ space_istk_border.axes_offsets_put(0,0);
+ array_iter_wrap<value_t> oldw(old_iter,space_istk_border);
+ std::cout<<oldw;
+ }
+ #endif
                         for
                           ( int s_node=0
                           ; s_node<s_space_inner
@@ -1584,11 +1664,12 @@
                               //the rhs of equation(19.41)
                               //of [DuffyFdm2006]
                               ;
- #ifdef TRACE_INTERIOR_RHS
+ #if TRACE_INTERIOR_RHS
+ ::boost::trace_scope
+ ts("rhs equations(19.41)");
                             std::cout
- <<":offset="<<offset
- <<":indices="<<space_istk_rotated.indices()
- <<":rhs_iter[offset]=old_iter[offset]="<<old_iter[offset]
+ <<":s_node="<<s_node<<"\n"
+ <<":rhs_iter=old_iter"<<space_istk_rotated.indices()<<"="<<old_iter[offset]
                               <<"\n"
                               ;
                           #endif
@@ -1599,39 +1680,60 @@
                               ; r_axis<s_rank-1
                               ; ++r_axis
                               )
- {//For axes whose derivatives appear on rhs of
+ {//For axes whose 2nd derivatives appear on rhs of
                              //equations(19.41) of [DuffyFdm2006]
- //sum those those derivatives into d2_sum.
+ //sum those derivatives into d2_sum.
                                   stride_t
                                 stride_v=space_istk_rotated[r_axis].stride_val();
- value_t
+ value_t
+ del_s_axis=space_axes[r_axis].del();
+ value_t
                                 d2_axis
                                   = ( old_iter[offset-stride_v]
                                     - 2*old_iter[offset]
                                     + old_iter[offset+stride_v]
                                     )
- / ( del_s2_v[r_axis]
- )
- ; //rhs of equation(18.13) of [DuffyFdm2006]
- //for axis, r_axis, at node, s_node.
+ / (del_s_axis*del_s_axis)
+ //rhs of equation(18.13) on page 197
+ //of [DuffyFdm2006]
+ //for axis, r_axis, at node, s_node.
+ ;
                                 d2_sum+=d2_axis;
+ #define TRACE_DERIV2_RHS (1 && TRACE_ALT_DIR_IMPLICIT_INNOCENT)
+ #if TRACE_DERIV2_RHS
+ ::boost::indent_scope<>
+ ts;//("deriv^2");
+ std::cout
+ <<":r_axis="<<r_axis
+ <<" :del_s_axis="<<del_s_axis
+ <<" :old_iter"
+ <<space_istk_rotated.indices_at_offset(offset-stride_v)
+ <<"="<<old_iter[offset-stride_v]
+ <<" :old_iter"
+ <<space_istk_rotated.indices_at_offset(offset+stride_v)
+ <<"="<<old_iter[offset+stride_v]
+ <<" :d2_axis="<<d2_axis
+ <<"\n"
+ ;
+ #endif
+ #undef TRACE_DERIV2_RHS
                             }//for(r_axis)
- rhs_iter[offset]+=dt_div_s_rank*d2_sum
+ rhs_iter[offset]+=del_t_frac*d2_sum
                               //This adds to rhs_iter
                               //the 2nd summand of
                               //the rhs of equations(19.41)
                               //of [DuffyFdm2006].
                               ;
- #ifdef TRACE_INTERIOR_RHS
+ #if TRACE_INTERIOR_RHS
                             std::cout
- <<":d2_sum="<<d2_sum
- <<":rhs_iter[offset]="<<rhs_iter[offset]
+ <<":d2_sum="<<d2_sum<<"\n"
+ <<":rhs_iter+=del_t_frac*d2_sum"<<space_istk_rotated.indices()<<"="<<rhs_iter[offset]
                               <<"\n"
                               ;
                           #endif
                         }//for(s_node)
                     }//interior_rhs
- #ifdef TRACE_FRACTIONAL_STEPS
+ #if TRACE_FRACTIONAL_STEPS
                     std::cout<<"rhs(after equations(19.41))=\n"<<rhs;
                   #endif
                     {//solve tridiagonal system.
@@ -1645,8 +1747,9 @@
                           struct
                         mk_tridiag
                         {
+ #define TRACE_MK_TRIDIAG (1 && TRACE_ALT_DIR_IMPLICIT_INNOCENT)
                                 typedef
- tridiag<value_t>
+ numeric::tridiag<value_t>
                             tridiag_t
                             ;
                                 static
@@ -1659,12 +1762,17 @@
                             {
                                   tridiag_t
                                 result=tridiag_t(std::size_t(n));
- value_t
+ value_t const
                                 dt_div_ds2=
                                   del_fract_t
                                   /
                                   ( del_s*del_s
                                   )
+ //this is the lambda of equation(19.4)
+ //of [DuffyFdm2006].
+ ;
+ value_t const
+ on_diag=1.0+2.0*dt_div_ds2
                                   ;
                                 for
                                   ( unsigned i=1
@@ -1677,9 +1785,9 @@
                                    * of [DuffyFdm2006].
                                    */
                                 {
- if(0<i)result.l(i)=-dt_div_ds2;
- result.d(i)=1.0+2*dt_div_ds2;
- if(i<n-1)result.u(i)=-dt_div_ds2;
+ if(0<i )result.l(i)=-dt_div_ds2;
+ result.d(i)=on_diag;
+ if( i<n-1)result.u(i)=-dt_div_ds2;
                                 }
                                 for
                                   ( unsigned i=0
@@ -1692,25 +1800,32 @@
                                    * of [DuffyFdm2006].
                                    */
                                 {
- if(0<i)result.l(i)=0.0;
+ if(0<i )result.l(i)=0.0;
                                     result.d(i)=1.0;//copy boundary condition from rhs.
- if(i<n-1)result.u(i)=0.0;
+ if( i<n-1)result.u(i)=0.0;
                                 }
+ #if TRACE_MK_TRIDIAG
+ std::cout
+ <<":del_fract_t="<<del_fract_t
+ <<":del_s="<<del_s
+ <<":dt_div_ds2="<<dt_div_ds2
+ <<":on_diag="<<on_diag
+ <<"\n:the_tridiag=\n"<<result
+ <<"\n";
+ #endif
                                 return result;
                             }
+ #undef TRACE_MK_TRIDIAG
                         };
- tridiag<value_t>
+ numeric::tridiag<value_t>
                         a_tridiag
                           = mk_tridiag::make
                             ( l_last
- , dt_div_s_rank
- , this->axes()[s_rank].del()
+ , del_t_frac
+ , space_axes[s_rank-1].del()
                             )
                           ;
- #ifdef TRACE_FRACTIONAL_STEPS
- std::cout<<"a_tridiag=\n"<<a_tridiag;
- #endif
- solve_tridiag<value_t>
+ numeric::solve_tridiag<value_t>
                         a_solver
                           ( space_istk_rotated
                           , a_tridiag
@@ -1721,12 +1836,12 @@
                         {
                             a_solver.upper_triangulate_rhs();
                             a_solver.back_substitute();
- #ifdef TRACE_FRACTIONAL_STEPS
- istk_indices_t space_istk_border(space_istk_is);
- space_istk_border.axes_offsets_put(0,0);
+ #if TRACE_FRACTIONAL_STEPS
                             //std::cout<<"rhs(after solve_tridiag)=\n"<<rhs<<".\n";
+ istk_indices_t space_istk_border(space_istk_rotated);
+ space_istk_border.axes_offsets_put(0,0);
                             array_iter_wrap<value_t> lhsw(lhs_iter,space_istk_border);
- std::cout<<"lhsw["<<i_time<<","<<(i_step+1)<<"](after solve_tridiag)=\n"
+ std::cout<<"lhsw_rotated["<<i_time<<","<<(i_step+1)<<"](after solve_tridiag)=\n"
                               <<lhsw<<".\n";
                           #endif
                         }
@@ -1740,7 +1855,7 @@
                         space_istk_rotated.axis_offsets_put(s_rank-1,1,1);
                     }//solve tridiagonal system.
                 }//for(i_step=0)
- #ifdef TRACE_EQUATIONS_19_34
+ #if TRACE_EQUATIONS_19_34
                 std::cout
                   <<":t_nxt="<<t_nxt
                   <<":t_frac="<<t_frac
@@ -1771,9 +1886,11 @@
                 }
             }//boundary_conditions_lhs
         }//for(i_time=...)
- std::cout<<"u["<<n_time<<"]=\n"<<u<<".\n";
- #undef TRACE_SOLN_DIFF_EQ
+ #if TRACE_SOLN_DIFF_EQ
+ std::cout<<":t_last="<<t_nxt<<"\n";
+ std::cout<<":u["<<(n_time-1)<<"]=\n"<<u<<".\n";
       #endif
+ #undef TRACE_SOLN_DIFF_EQ
     }
 };//exit diff_alt_dir_implicit_innocent
 #endif
@@ -1827,54 +1944,28 @@
     funcs_t
       ;
       value_t
- exact_indices
- ( value_t t_val
- , istk_indices_t const& s_iter
- )
- /**@brief
- * The fundamental solution to heat equation:
- * References:
- * [Churchill72]
- * problem 8, page 150 of:
- * _Operational Mathematics_
- * Ruel V. Churchill
- * McGraw-Hill, 1972.
- * [Wiki2011]
- * http: * en.wikipedia.org/wiki/Heat_equation#Fundamental_solutions
- * However:
- * [Wiki2011] differs from [Churchill72] slightly:
- * [Wiki2011] has pow( 4*Pi*k*t, n/2) whereas
- * [Churchill72] has sqrt(t).
- * Since, in [Churchill72], the dimensionality, n=1,
- * that's almost the same, the only difference being
- * a constant factor, pow(4*Pi*k, n/2), both solution functions
- * satisfy the homogeneous equation if either does.
- **@requires
- * WHAT:
- * t_zero<=t_val, for some "large enough" t_zero.
- * WHY:
- * See ss_divisor comments below.
- */
+ exact_values
+ ( std::vector<value_t>const& a_vals
+ )
       {
- //#define TRACE_EXACT_INDICES
- #ifdef TRACE_EXACT_INDICES
+ //#define TRACE_EXACT_VALUES
+ #ifdef TRACE_EXACT_VALUES
           ::boost::trace_scope ts("exact_indices");
           std::cout<<":t_val="<<t_val<<":s_iter="<<s_iter<<"\n";
         #endif
             value_t
           sumsq=0.0;
             unsigned
- s_rank=s_iter.rank();
+ s_rank=a_vals.size()-1;
           for(unsigned s_axis=0; s_axis<s_rank; ++s_axis)
           {
                 value_t const
               s_val
- = this->axes()
+ = a_vals
                   [ s_axis+1]
- [ s_iter[s_axis].template get<index_value>() ]
                 ;
               sumsq+=s_val*s_val;
- #ifdef TRACE_EXACT_INDICES
+ #ifdef TRACE_EXACT_VALUES
               std::cout<<":s_val="<<s_val<<":sumsq="<<sumsq<<"\n";
             #endif
           }
@@ -1886,25 +1977,48 @@
             //in [Wiki2011].
             ;
             value_t
+ t_val=a_vals[0];
+ value_t
           ss_divisor=4.0*(this->diffusivity)*t_val
             //sum squares divisor.
- // t_val must be not be 0; otherwise, divide by zero occurs
+ // t_val must not be 0; otherwise, divide by zero occurs
             // in next statement, in 2 places.
             // To avoid rounding errors, it must be greater than 0.0
             // by some unknown amount(0.1 seems to work when
             // diffusivity==1.0).
             ;
- #ifdef TRACE_EXACT_INDICES
+ #ifdef TRACE_EXACT_VALUES
           std::cout<<":ss_divisor="<<ss_divisor<<"\n";
         #endif
             value_t
- u_val=exp(-sumsq/ss_divisor)/pow(t_val,s_rank_div_2);
- #ifdef TRACE_EXACT_INDICES
- std::cout<<":u_val="<<u_val<<"\n";
+ result=exp(-sumsq/ss_divisor)/pow(t_val,s_rank_div_2);
+ #ifdef TRACE_EXACT_VALUES
+ std::cout<<":result="<<result<<"\n";
         #endif
- return u_val;
+ return result;
+ #undef TRACE_EXACT_VALUES
       }
       
+ value_t
+ exact_indices
+ ( value_t t_val
+ , istk_indices_t const& s_iter
+ )
+ {
+ unsigned const s_rank=s_iter.rank();
+ std::vector<value_t> vals(s_rank+1);
+ vals[0]=t_val;
+ for(unsigned s_axis=0; s_axis<s_rank; ++s_axis)
+ {
+ vals[s_axis+1]
+ = this->axes()
+ [ s_axis+1]
+ [ s_iter[s_axis].template get<index_value>() ]
+ ;
+ }
+ return exact_values(vals);
+ }
+
       value_t
     ic_indices( istk_indices_t const& s_iter)
       {//initial conditions at indices, i_iter.
@@ -1967,26 +2081,41 @@
     solver.solve_estim_err();
 };
 
+#include <fstream>
+
 int main()
 {
     boost::iostreams::indent_scoped_ostreambuf<char> indent_outbuf(std::cout,2);
         typedef
       grid_axis_size_bounds<value_t>
     grid_bounds_t;
- grid_axes_diff<value_t>
- grid_axes
- ({ grid_bounds_t( 3, 0.1, 1.0)
- #if 1
- , grid_bounds_t( 10, 0.0, 1.0)
- , grid_bounds_t( 9, 0.0, 1.0)
- #else
- , grid_bounds_t( 3, 0.0, 1.0)
- , grid_bounds_t( 4, 0.0, 1.0)
- , grid_bounds_t( 5, 0.0, 1.0)
- #endif
- }
- )
+
+ char const*
+ axes_file_name="diff_pde.inp";
+ std::ifstream
+ axes_file_strm(axes_file_name);
+ if(!axes_file_strm)
+ {
+ std::cerr<<"cannot open "<<axes_file_name<<"\n";
+ std::exit(1);
+ }
+ std::vector<grid_bounds_t>
+ axes_vec
       ;
+ for
+ ( unsigned i_axis
+ ; i_axis<10
+ ; ++i_axis
+ )
+ {
+ grid_bounds_t a_axes;
+ axes_file_strm>>a_axes;
+ if(axes_file_strm.eof())break;
+ axes_vec.push_back(a_axes);
+ };
+ std::cout<<":axes_vec=\n"<<axes_vec<<"\n";
+ grid_axes_diff<value_t>
+ grid_axes( axes_vec);
     std::cout<<grid_axes;
     #ifdef DIFF_ALT_DIR_EXPLICIT
     {

Modified: sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/index_stack_length_stride_crtp~demo.cpp
==============================================================================
--- sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/index_stack_length_stride_crtp~demo.cpp (original)
+++ sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/index_stack_length_stride_crtp~demo.cpp 2011-11-07 10:12:03 EST (Mon, 07 Nov 2011)
@@ -22,7 +22,10 @@
         for(unsigned node=0; node<space; ++node, lsos_v.template inc_dec_ator<ID>())
         {
             std::cout<<"node["<<std::setw(2)<<node<<"]=";
- std::cout<<lsos_v<<"\n";
+ std::cout<<lsos_v;
+ auto offset=lsos_v.offset_space_val();
+ std::cout<<", indices_at_offset="<<lsos_v.indices_at_offset(offset);
+ std::cout<<"\n";
         }
     }
 }
@@ -52,20 +55,20 @@
     typedef types_t::axis_t axis_t;
     axis_t axis_v=2;
     index_t offset_v=1;
- lsos_v.axis_offset_put(axis_v,offset_v,offset_v);
- std::cout<<"axis_offset_put("<<axis_v<<","<<offset_v<<","<<offset_v<<"):\n";
+ lsos_v.axis_offsets_put(axis_v,offset_v,offset_v);
+ std::cout<<"axis_offsets_put("<<axis_v<<","<<offset_v<<","<<offset_v<<"):\n";
     lsos_v.axis_index_put(axis_v,lsos_v[axis_v].get<index_bound_lower>());
     std::cout<<"axis_index_put("<<axis_v<<",index_bound_lower["<<axis_v<<"]):\n";
     test_inc_dec<inc_ator>(lsos_v);
     offset_v=0;
- lsos_v.axis_offset_put(axis_v,offset_v,offset_v);
- std::cout<<"axis_offset_put("<<axis_v<<","<<offset_v<<","<<offset_v<<"):\n";
+ lsos_v.axis_offsets_put(axis_v,offset_v,offset_v);
+ std::cout<<"axis_offsets_put("<<axis_v<<","<<offset_v<<","<<offset_v<<"):\n";
     lsos_v.axis_index_put(axis_v,lsos_v[axis_v].get<index_bound_lower>());
     std::cout<<"axis_index_put("<<axis_v<<",index_bound_lower["<<axis_v<<"]):\n";
     test_inc_dec<inc_ator>(lsos_v);
     auto offset_l=lsos_v[axis_v].length_val()-1;
- lsos_v.axis_offset_put(axis_v,offset_l,offset_v);
- std::cout<<"axis_offset_put("<<axis_v<<","<<offset_l<<","<<offset_v<<"):\n";
+ lsos_v.axis_offsets_put(axis_v,offset_l,offset_v);
+ std::cout<<"axis_offsets_put("<<axis_v<<","<<offset_l<<","<<offset_v<<"):\n";
     lsos_v.axis_index_put(axis_v,lsos_v[axis_v].get<index_bound_lower>());
     std::cout<<"axis_index_put("<<axis_v<<",index_bound_lower["<<axis_v<<"]):\n";
     test_inc_dec<inc_ator>(lsos_v);

Modified: sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/solve_tridiag.cpp
==============================================================================
--- sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/solve_tridiag.cpp (original)
+++ sandbox/variadic_templates/sandbox/stepper/libs/array_stepper/examples/solve_tridiag.cpp 2011-11-07 10:12:03 EST (Mon, 07 Nov 2011)
@@ -1,5 +1,5 @@
 #include <boost/utility/trace_scope.hpp>
-#include <boost/array_stepper/solve_tridiag.hpp>
+#include <boost/array_stepper/numeric/solve_tridiag.hpp>
 #include <boost/array_stepper/array_dyn.hpp>
 #include <boost/array_stepper/array_store_print.hpp>
 using namespace boost::array_stepper;
@@ -17,10 +17,10 @@
   {
       std::size_t const n=4;
       typedef double value_t;
- typedef tridiag<value_t> trid_t;
+ typedef numeric::tridiag<value_t> trid_t;
       typedef std::vector<value_t> vv_t;
         trid_t
- a( tridiag_seq_seq_tag()
+ a( numeric::tridiag_seq_seq_tag()
        , std::vector< vv_t>
          ( { { -3.0, -2.0, 1.0} //upper
            , { 5.0, 4.0, 3.0, 5.0} //diagonal
@@ -122,7 +122,7 @@
           trid_t la(a);
           array_t lr(r);
           array_t x(lengths_soln);
- solve_tridiag<value_t> tds( istk_v, la, lr.data().begin(), x.data().begin());
+ numeric::solve_tridiag<value_t> tds( istk_v, la, lr.data().begin(), x.data().begin());
           if( tds.upper_triangulate_trid(zero_tol))
           {
               tds.upper_triangulate_rhs();


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk