# No. 447 (Brown 1868): the flying ferry.
# Model (cm, plan view from above). A river 36 cm wide runs left to right between two banks. The water is particles in the plan,
# across the boat's draught (src/fluid/, about 0.65 cm apart, each pushing what it touches), fed across the whole width upstream at
# 36 cm/s and leaving downstream off the picture. A boat 12 cm long hangs at its bow on a cable 36 cm long from an anchor in
# mid-river upstream: the cable swings about the anchor and the boat turns freely about the cable's end. Its rudder is set
# 35 degrees off the keel. Nothing is driven: the current on the hull and rudder is the only input. The boat starts by the
# near bank, lying down the stream; the current sets it at an angle and carries it across in an arc about the anchor.
# Generator: opencode-runs/water/gen447.py.
number: 447
slug: flying-ferry
name: Flying ferry
brown: "This method of passing a boat from one shore of a river to the other is common on the Rhine and elsewhere, and is effected by the action of the stream on the rudder, which carries the boat across the stream in the arc of a circle, the center of which is the anchor which holds the boat from floating down the stream."
units: cm
sim:
  timestep: 0.002
  integrator: implicitfast
  iterations: 50
  duration_s: 12
  floor: false
bodies:
  - id: cable
    shape: part
    pos: [-50, 0, 0]
    density: 300
    friction: 0
    color: "#6d5a3e"
    pieces:
      - {kind: rod, from: [-50, 0, 1.2], to: [-16.1711, -12.3127, 1.2], radius: 0.12, color: "#6d5a3e"}   # the cable (held up clear of the water)
  - id: boat
    shape: part
    pos: [-16.1711, -12.3127, 0]
    mount: cable
    density: 450
    friction: 0
    color: "#9c7a4e"
    pieces:
      - {kind: loft, a: [[-18.9901, -11.2867, -0.6], [-17.1104, -10.8002, -0.6], [-7.3376, -14.3572, -0.6], [-8.0901, -16.4246, -0.6], [-17.8629, -12.8676, -0.6]], b: [[-18.9901, -11.2867, 0.6], [-17.1104, -10.8002, 0.6], [-7.3376, -14.3572, 0.6], [-8.0901, -16.4246, 0.6], [-17.8629, -12.8676, 0.6]], collide: 2}   # the hull, through the water's depth
      - {kind: loft, a: [[-7.6091, -15.307, -0.6], [-2.7795, -14.0129, -0.6], [-2.707, -14.2833, -0.6], [-7.5366, -15.5774, -0.6]], b: [[-7.6091, -15.307, 0.6], [-2.7795, -14.0129, 0.6], [-2.707, -14.2833, 0.6], [-7.5366, -15.5774, 0.6]], collide: 2, color: "#7a5c38"}   # the rudder, set 35 degrees
      - {kind: loft, a: [[-18.6143, -11.4235, 0.6], [-17.008, -11.1036, 0.6], [-7.658, -14.5067, 0.6], [-8.2395, -16.1041, 0.6], [-17.5894, -12.701, 0.6]], b: [[-18.6143, -11.4235, 0.85], [-17.008, -11.1036, 0.85], [-7.658, -14.5067, 0.85], [-8.2395, -16.1041, 0.85], [-17.5894, -12.701, 0.85]], color: "#c2a273"}   # the deck
      - {kind: loft, a: [[-15.0091, -12.0439, 0.85], [-10.7804, -13.583, 0.85], [-11.2251, -14.8046, 0.85], [-15.4537, -13.2655, 0.85]], b: [[-15.0091, -12.0439, 2.2], [-10.7804, -13.583, 2.2], [-11.2251, -14.8046, 2.2], [-15.4537, -13.2655, 2.2]], color: "#8a6a44"}   # the cabin
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    friction: 0
    color: "#a8946c"
    pieces:
      - {kind: poly, points: [[-72, -1.5], [42, -1.5], [42, 1.6], [-72, 1.6]], y: [-19.2, -18], collide: 2, color: "#a8946c"}   # the near bank
      - {kind: poly, points: [[-72, -1.5], [42, -1.5], [42, 1.6], [-72, 1.6]], y: [18, 19.2], collide: 2, color: "#a8946c"}   # the far bank
      - {kind: poly, points: [[-72, -2.6], [42, -2.6], [42, -2.4], [-72, -2.4]], y: [-18, 18], color: "#9a9478"}   # the river's bed, under the water
      - {kind: poly, points: [[-67, -1.5], [-66.2, -1.5], [-66.2, 1.6], [-67, 1.6]], y: [-19.2, 19.2], collide: 2, color: "#a8946c"}   # the weir upstream, off the picture: the reservoir's water cannot run back out
      - {kind: rod, from: [-50, 0, -1.5], to: [-50, 0, 1.6], radius: 0.45, color: "#4a4a48"}   # the anchor's buoy (the anchor rides on the bed)
joints:
  - {id: j_c, type: hinge, body: cable, axis: [0, 0, 1], damping: 0}   # + : the cable swings from the near bank (y < 0) towards the far bank
  - {id: j_b, type: hinge, body: boat, axis: [0, 0, 1]}
contact: {solref: [0.003, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_c, kind: torque, torque: 0, max_torque: 0.001}   # no hand: the current is the only input
checks:
  - {type: monotonic, joint: j_c, direction: 1, max_back: 0.05, settle_s: 1.0, window_s: 10.0}
  - {type: position, joint: j_c, min: 0.6981, max: 1.0472, settle_s: 11.0, window_s: 0.9}   # carried across: the cable well past mid-river by the end
  - {type: penetration, max: 0.003}
fluid:
  plane: xy
  slab: [-0.6, 0.6]
  spacing: 0.65
  dt: 0.002
  iterations: 3
  friction: 0.005
  domain: [-67, -19, 38, 19]
  reservoir: {box: [-66, -18, -63, 18], head: 18, emit: [36, 0]}   # upstream: kept full, the water leaving at the current's speed
  fill: [[-63, -18, -19.6901, 18], [-2.007, -18, 36, 18], [-19.6901, -18, -2.007, -17.1246], [-19.6901, -10.1002, -2.007, 18]]
  sinks: [[35, -19, 38, 19]]
  draw: surface
  tiers: [{id: light, label: "Lighter water (fewer particles)", spacing: 0.8125, iterations: 2}]
display:
  output: j_c
  labels: {j_c: "Cable", j_b: "Boat on the cable"}
  caption: top
camera: {target: [-14, 4.8, 0], position: [-14, 4.3, 150], fov: 19.5}
