| 1 | module sim |
| 2 | |
| 3 | import math |
| 4 | import benchmark |
| 5 | |
| 6 | const max_iterations = 1000 |
| 7 | const simulation_delta_t = 0.0005 |
| 8 | |
| 9 | pub struct SimRequest { |
| 10 | pub: |
| 11 | params SimParams |
| 12 | state SimState |
| 13 | id int |
| 14 | } |
| 15 | |
| 16 | pub struct SimResult { |
| 17 | state SimState |
| 18 | pub: |
| 19 | id int |
| 20 | magnet1_distance f64 |
| 21 | magnet2_distance f64 |
| 22 | magnet3_distance f64 |
| 23 | } |
| 24 | |
| 25 | pub fn sim_worker(id int, request_chan chan &SimRequest, result_channels []chan &SimResult) { |
| 26 | mut bmark := benchmark.new_benchmark() |
| 27 | for { |
| 28 | request := <-request_chan or { break } |
| 29 | bmark.step() |
| 30 | result := compute_result(request) |
| 31 | for ch in result_channels { |
| 32 | ch <- result |
| 33 | } |
| 34 | bmark.ok() |
| 35 | } |
| 36 | bmark.stop() |
| 37 | println(bmark.total_message(@FN + ': worker ${id}')) |
| 38 | } |
| 39 | |
| 40 | pub fn compute_result(request SimRequest) &SimResult { |
| 41 | mut state := request.state |
| 42 | params := request.params |
| 43 | |
| 44 | for _ in 0 .. max_iterations { |
| 45 | state.increment(simulation_delta_t, params) |
| 46 | if state.done() { |
| 47 | println('done!') |
| 48 | break |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | m1_dist := params.get_magnet_dist(0, state) |
| 53 | m2_dist := params.get_magnet_dist(2.0 * math.pi / 3.0, state) |
| 54 | m3_dist := params.get_magnet_dist(4.0 * math.pi / 3.0, state) |
| 55 | |
| 56 | id := request.id |
| 57 | |
| 58 | return &SimResult{ |
| 59 | id: id |
| 60 | state: state |
| 61 | magnet1_distance: m1_dist |
| 62 | magnet2_distance: m2_dist |
| 63 | magnet3_distance: m3_dist |
| 64 | } |
| 65 | } |
| 66 | |