Using External Meandering Code


I've translated the Topographic Steering model from C++ into Python and can call it from Child. The interface between the programs is still in text, but I keep the external program running and the connection open between calls, which speeds things up considerably. Below is an excerpt from calling the C++ and Python TS code with the same inputs at one of the iterations. The simulation is initialized by calling a Python program for the first 100 iterations to shape the river into a sine wave with 5 cycles. After that point, the TS model is called, either within Child or from Python. The text interface only preserves 6 decimal places of precision, which accounts for the slight differences in output. Only a few points near the beginning and end of the meandering reach are shown:

time = 100, stations = 101, stnserod = 101

    i              x              y             xs           dels          flow          rerody        lerody           slope          width          depth           diam         lambda
----- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- 
   11     476.746768     860.000000     152.109314      18.505024      28.519279       0.010000       0.010000       0.007015      10.000000       2.500000       0.010000      16.021033
   12     461.176414     850.000000     170.614338      16.392017      28.519279       0.010000       0.010000       0.006995      10.000000       2.500000       0.010000      16.021033
   13     448.188026     840.000000     187.006355      13.458087      28.519279       0.010000       0.010000       0.006851      10.000000       2.500000       0.010000      16.021033
   14     439.181355     830.000000     200.464443      10.785157      28.519279       0.010000       0.010000       0.006792      10.000000       2.500000       0.010000      16.021033
   15     435.141601     820.000000     211.249600      10.091472      28.519279       0.010000       0.010000       0.006393      10.000000       2.500000       0.010000      16.021033
   16     436.497260     810.000000     221.341072      11.991945      28.519279       0.010000       0.010000       0.006060      10.000000       2.500000       0.010000      16.021033

   91     476.740684     100.000000    1291.980175      18.504855      28.519279       0.010000       0.010000       0.006265      10.000000       2.500000       0.010000      16.021033
   92     461.170532      90.000000    1310.485030      16.387356      28.519279       0.010000       0.010000       0.005887      10.000000       2.500000       0.010000      16.021033
   93     448.188026      80.000000    1326.872386      13.455312      28.519279       0.010000       0.010000       0.005410      10.000000       2.500000       0.010000      16.021033
   94     439.185503      70.000000    1340.327698      10.784587      28.519279       0.010000       0.010000       0.005173      10.000000       2.500000       0.010000      16.021033
   95     435.147272      60.000000    1351.112285      10.091714      28.519279       0.010000       0.010000       0.004741      10.000000       2.500000       0.010000      16.021033
   96     436.504729      50.000000    1361.203999      11.987824      28.519279       0.010000       0.010000       0.004180      10.000000       2.500000       0.010000      16.021033
   97     443.115926      40.000000    1373.191823      14.973170      28.519279       0.010000       0.010000       0.003570      10.000000       2.500000       0.010000      16.021033

(C++)

    i           delx           dely     rightdepth      leftdepth
----- -------------- -------------- -------------- --------------
   11       0.000000      -0.000000       2.500000       2.500000
   12       0.003526      -0.005489       2.597828       2.402172
   13       0.013292      -0.017265       2.768412       2.231588
   14       0.015461      -0.013925       3.138792       1.861208
   15       0.008493      -0.003431       3.985923       1.014077
   16       0.000000       0.000000       4.833604       0.166396

   91       0.000000      -0.000000       2.500000       2.500000
   92       0.001946      -0.003031       2.581122       2.418878
   93       0.010314      -0.013390       2.706758       2.293242
   94       0.016213      -0.014596       2.963964       2.036036
   95       0.011409      -0.004607       3.544338       1.455662
   96       0.004630       0.000629       4.141891       0.858109
   97       0.000000       0.000000       3.692731       1.307269

(Python)

    i           delx           dely     rightdepth      leftdepth
----- -------------- -------------- -------------- --------------
   11       0.000000      -0.000000       2.503898       2.496102
   12       0.003528      -0.005494       2.597839       2.402161
   13       0.013296      -0.017270       2.768384       2.231616
   14       0.015459      -0.013923       3.138870       1.861130
   15       0.008489      -0.003429       3.985834       1.014166
   16       0.000000       0.000000       4.833805       0.166195

   91       0.000000      -0.000000       2.500000       2.500000
   92       0.001945      -0.003029       2.581124       2.418876
   93       0.010311      -0.013387       2.706773       2.293227
   94       0.016213      -0.014596       2.963948       2.036052
   95       0.011411      -0.004608       3.544400       1.455600
   96       0.004632       0.000629       4.141945       0.858055
   97       0.000000       0.000000       3.692812       1.307188

The entire output (one iteration) for 101 points is here. The simulation domain is 1000x1000 m, the channel is 10x2.5 m.

Here are the C++ results for 100, 500, 1000, 2000, 5000, and 10000 iterations:


(Click for larger image)

Here are the Python results for 100, 500, 1000, 2000, 5000, and 10000 iterations:
(I guess that 7th decimal place, etc.., makes a big difference 8^) )


(Click for larger image)

Here is a 3d comparison of the final result for 10000 iterations (Z is exaggerated 25x):


(Click for larger image)

The full run of 10000 iterations took 18 min 24 secs for C++, and 26 min 1 sec for Python (about 1.4 : 1), although I suspect that most of the extra time was spent in encoding and decoding floating-point numbers. For additional speed, I could pass the 8-byte reals as binary, but that would make debugging the external output much more difficult. I guess I'm fairly happy with the speed at present.

I'm now ready to start developing additional meandering code using the external system. I'll be working on the Johannesson-Parker 1989 method during the next 2 months. However, many additional models are possible. Using an external program makes it easy to try different methods, and to edit methods, without having to edit or recompile Child.

For example, shown below is a naive physical model in which (a) the lateral force necessary to accelerate the flow mass (via change of direction, not speed) is calculated at each point, and then (b) the change in (x, y) position of each point is calculated proportional to the sqrt of the sum of the lateral forces acting at the current point and the previous 2 points in the stream. This has the effect of both smoothing the forces and delaying their action downstream (via spatial integration), both of which seem to be essential features of a 'good' meandering model (such as TS).

Here is output at 100, 500, 1000, 2000, 3000, and 4000 iterations:


(Click for larger image)


© Sky Coyote 2008.