-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocs.html
More file actions
3400 lines (3081 loc) · 197 KB
/
docs.html
File metadata and controls
3400 lines (3081 loc) · 197 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/svg+xml" href="favicon.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WindMar Documentation - Technical Reference</title>
<link rel="stylesheet" href="assets/css/docs.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js"></script>
</head>
<body>
<!-- Header -->
<header class="docs-header">
<div class="docs-header-content">
<a href="docs.html" class="docs-logo">
<i class="fas fa-ship"></i>
<span>WindMar</span>
</a>
<nav>
<ul class="docs-nav">
<li><a href="docs.html" class="active">Documentation</a></li>
<li class="docs-nav-dropdown">
<a href="#">Technical Articles <i class="fas fa-caret-down"></i></a>
<ul class="docs-nav-dropdown-menu">
<li><a href="weather-fields.html">Weather Fields</a></li>
<li><a href="data-pipeline.html">Data Pipeline</a></li>
<li><a href="hydrodynamics.html">Hydrodynamics & RAO</a></li>
<li><a href="astar-pathfinding.html">A* Pathfinding</a></li>
<li><a href="route-optimization-engines.html">Optimization Engines</a></li>
<li><a href="weather-data.html">Weather Acquisition</a></li>
<li><a href="monte-carlo.html">Monte Carlo</a></li>
<li><a href="open-problems.html">Open Problems</a></li>
</ul>
</li>
<li><a href="https://github.com/windmar-nav/windmar" target="_blank"><i class="fab fa-github"></i> GitHub</a></li>
<li><a href="https://github.com/windmar-nav/windmar#try-it-locally" class="demo-nav-link" target="_blank"><i class="fas fa-download"></i> Install Now</a></li>
</ul>
</nav>
<a href="project.html" class="back-to-main"><i class="fas fa-arrow-left"></i> Back to Main Site</a>
</div>
</header>
<!-- Main Layout -->
<div class="docs-container">
<!-- Sidebar -->
<aside class="docs-sidebar">
<div class="sidebar-section">
<div class="sidebar-title">Getting Started</div>
<ul class="sidebar-menu">
<li><a href="#overview"><i class="fas fa-home"></i> Overview</a></li>
<li><a href="#architecture"><i class="fas fa-sitemap"></i> Architecture</a></li>
<li><a href="#installation"><i class="fas fa-download"></i> Installation</a></li>
<li><a href="#tech-stack"><i class="fas fa-layer-group"></i> Tech Stack</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Physical Models</div>
<ul class="sidebar-menu">
<li><a href="#calm-water"><i class="fas fa-water"></i> Calm Water Resistance</a></li>
<li><a href="#wind-resistance"><i class="fas fa-wind"></i> Wind Resistance</a></li>
<li><a href="#wave-resistance"><i class="fas fa-wave-square"></i> Wave Resistance</a></li>
<li><a href="#sfoc-curve"><i class="fas fa-gas-pump"></i> SFOC Curve</a></li>
<li><a href="#propulsion-chain"><i class="fas fa-cog"></i> Propulsion Chain</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Seakeeping</div>
<ul class="sidebar-menu">
<li><a href="#ship-motions"><i class="fas fa-arrows-alt"></i> Ship Motions</a></li>
<li><a href="#safety-criteria"><i class="fas fa-shield-alt"></i> Safety Criteria</a></li>
<li><a href="#slamming-roll"><i class="fas fa-exclamation-triangle"></i> Slamming & Roll</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Route Optimization</div>
<ul class="sidebar-menu">
<li><a href="#astar-algorithm"><i class="fas fa-route"></i> A* Algorithm</a></li>
<li><a href="#variable-speed"><i class="fas fa-tachometer-alt"></i> Variable Speed</a></li>
<li><a href="#safety-constraints"><i class="fas fa-ban"></i> Safety Constraints</a></li>
<li><a href="#gshhs-coastline"><i class="fas fa-globe-americas"></i> GSHHS Coastline</a></li>
<li><a href="#variable-resolution"><i class="fas fa-th"></i> Variable Resolution</a></li>
<li><a href="#strait-shortcuts"><i class="fas fa-draw-polygon"></i> Strait Shortcuts</a></li>
<li><a href="#pareto-front"><i class="fas fa-chart-area"></i> Pareto Front</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Compliance</div>
<ul class="sidebar-menu">
<li><a href="#cii-rating"><i class="fas fa-certificate"></i> IMO CII Rating</a></li>
<li><a href="#fueleu-maritime"><i class="fas fa-leaf"></i> FuelEU Maritime</a></li>
<li><a href="#voyage-reporting"><i class="fas fa-file-alt"></i> Voyage Reporting</a></li>
<li><a href="#charter-party"><i class="fas fa-handshake"></i> Charter Party Clauses</a></li>
<li><a href="#regulatory-zones"><i class="fas fa-map-marked-alt"></i> Regulatory Zones</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Weather Data</div>
<ul class="sidebar-menu">
<li><a href="weather-data.html"><i class="fas fa-cloud-sun-rain"></i> Weather Data Acquisition</a></li>
<li><a href="#weather-database"><i class="fas fa-database"></i> Weather Database</a></li>
<li><a href="#forecast-timeline"><i class="fas fa-clock"></i> Forecast Timeline</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Monte Carlo</div>
<ul class="sidebar-menu">
<li><a href="#monte-carlo"><i class="fas fa-dice"></i> Simulation Engine</a></li>
<li><a href="monte-carlo.html"><i class="fas fa-book"></i> Technical Article</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">API Reference</div>
<ul class="sidebar-menu">
<li><a href="#weather-api"><i class="fas fa-cloud-sun"></i> Weather API</a></li>
<li><a href="#route-api"><i class="fas fa-directions"></i> Route API</a></li>
<li><a href="#vessel-api"><i class="fas fa-anchor"></i> Vessel API</a></li>
<li><a href="#performance-predictor"><i class="fas fa-tachometer-alt"></i> Performance Predictor</a></li>
<li><a href="#engine-log-api"><i class="fas fa-clipboard-list"></i> Engine Log API</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Validation</div>
<ul class="sidebar-menu">
<li><a href="#model-validation"><i class="fas fa-check-circle"></i> Model Validation</a></li>
<li><a href="#calibration"><i class="fas fa-sliders-h"></i> Calibration</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Gallery</div>
<ul class="sidebar-menu">
<li><a href="#gallery"><i class="fas fa-images"></i> Screenshots</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Technical Articles</div>
<ul class="sidebar-menu">
<li><a href="#technical-articles"><i class="fas fa-newspaper"></i> Article Index</a></li>
<li><a href="weather-fields.html"><i class="fas fa-cloud-sun"></i> Weather Fields</a></li>
<li><a href="data-pipeline.html"><i class="fas fa-database"></i> Data Pipeline</a></li>
<li><a href="hydrodynamics.html"><i class="fas fa-water"></i> Hydrodynamics & RAO</a></li>
<li><a href="astar-pathfinding.html"><i class="fas fa-route"></i> A* Pathfinding</a></li>
<li><a href="weather-data.html"><i class="fas fa-cloud-sun-rain"></i> Weather Acquisition</a></li>
<li><a href="monte-carlo.html"><i class="fas fa-dice"></i> Monte Carlo</a></li>
<li><a href="open-problems.html"><i class="fas fa-compass"></i> Open Problems</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-title">Resources</div>
<ul class="sidebar-menu">
<li><a href="https://github.com/windmar-nav/windmar" target="_blank"><i class="fab fa-github"></i> GitHub</a></li>
</ul>
</div>
</aside>
<!-- Main Content -->
<main class="docs-main">
<div class="docs-content">
<!-- ============================================================ -->
<!-- OVERVIEW -->
<!-- ============================================================ -->
<section id="overview">
<h1>WindMar Technical Documentation</h1>
<p class="docs-subtitle">Weather routing & performance analytics for merchant ships</p>
<div class="alert" style="background: rgba(76, 175, 80, 0.08); border-left: 4px solid #4caf50; padding: 1rem 1.25rem; margin-bottom: 1.5rem;">
<strong><i class="fas fa-code-branch"></i> Development Log</strong>
<span style="display: inline-flex; align-items: center; gap: 0.4rem; background: rgba(76, 175, 80, 0.12); border: 1px solid rgba(76, 175, 80, 0.3); color: #66bb6a; padding: 0.15rem 0.65rem; border-radius: 1rem; font-size: 0.8rem; font-weight: 600; margin-left: 0.5rem; vertical-align: middle;">
<i class="fas fa-tag"></i> v0.1.5 — Latest Stable
</span>
<table style="width: 100%; margin-top: 0.75rem; font-size: 0.9rem; border-collapse: collapse;">
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.1.3</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-27</td>
<td style="padding: 0.35rem 0;">Global weather coverage (7 layers, ±60° lat, raster tiles → client-side canvas), WMO-standard wind barbs (calm circle, pennants, half/full barbs), calm wind zone coloring, double-buffered canvas rendering, gzip weather cache, ice land masking, SST coastline bleed fix, currents-over-land fix, settings page 2-column card layout, ~72K LOC</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.1.2</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-25</td>
<td style="padding: 0.35rem 0;">Dedicated Settings page with optimization engine configuration and educational content, per-leg variable speed optimization (fuel ~ speed³), session persistence (sessionStorage-backed React Context), demo mode hardening (locked viewport, hidden uploads, frozen weather), Dijkstra node budget reduction</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.1.1</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-24</td>
<td style="padding: 0.35rem 0;">Weather pipeline fixes: wind DB rebuild, SST black holes, wave OOM crash, weather debug endpoint, cache versioning, NaN sentinels, viewport margin & latitude cap widening (±55° → ±60°)</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.1.0</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-22</td>
<td style="padding: 0.35rem 0;">Commercial compliance (CII, FuelEU Maritime, charter party tools, voyage reporting) + production optimizer (GSHHS coastline, 9 strait shortcuts, Pareto front, course-change penalty, safety fallback, A*-primary with optional VISIR) + security hardening (pickle RCE fix, input bounds, CORS, rate limits, NaN/Inf sanitization), ~67K LOC, 734 tests</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.0.9</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-20</td>
<td style="padding: 0.35rem 0;">Modular architecture refactoring (6,922→281 LOC main.py, 9 domain routers, 37 Pydantic schemas), calibration improvements (ME-specific fuel, laden/ballast detection from ME load %, widened bounds), engine log deduplication, 426 tests passing</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.0.8</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-18</td>
<td style="padding: 0.35rem 0;">Vessel model upgrade (SFOC calibration fix, Kwon + STAWAVE-1 dual wave methods, bisection performance predictor), engine log analytics (CSV/Excel upload, 5 KPIs, 6 charts, calibration bridge), weather pipeline refactoring (user-triggered overlays, viewport-aware resync, deferred supersede), Dijkstra cost formula fix (safety on fuel only), hard avoidance limits (Hs ≥ 6 m, wind ≥ 70 kts), dashboard layout harmonization, 79 API endpoints</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.0.7</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-13</td>
<td style="padding: 0.35rem 0;">Two-mode architecture (Weather/Analysis), 7 weather layers with WMO color ramps, forecast timeline for all layers, analysis panel + detail page with per-waypoint passage plan, route save/load, current & wave direction in results, Monte Carlo P10/P50/P90, vessel speed sync</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.0.6</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-10</td>
<td style="padding: 0.35rem 0;">ECDIS-style UI redesign, dual speed-strategy optimization (Same Speed / Match ETA), voyage baseline gating, wave crest rendering with polar diagram, GFS wind DB ingestion, turn-angle path smoothing</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af; width: 5rem;"><strong>v0.0.5</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280; width: 6rem;">2026-02-09</td>
<td style="padding: 0.35rem 0;">Weather DB architecture, temporal weather provisioning, Monte Carlo with correlated perturbations, CII compliance, PostgreSQL persistence</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af;"><strong>v0.0.4</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280;">2026-02-09</td>
<td style="padding: 0.35rem 0;">Frontend refactor, Monte Carlo simulation, grid weather provider</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af;"><strong>v0.0.3</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280;">2026-02-09</td>
<td style="padding: 0.35rem 0;">Data sources docs, credential setup, modernize pyproject.toml</td>
</tr>
<tr style="border-bottom: 1px solid rgba(255,255,255,0.06);">
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af;"><strong>v0.0.2</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280;">2026-02-08</td>
<td style="padding: 0.35rem 0;">GFS near-real-time wind data + 5-day forecast timeline</td>
</tr>
<tr>
<td style="padding: 0.35rem 0; white-space: nowrap; color: #9ca3af;"><strong>v0.0.1</strong></td>
<td style="padding: 0.35rem 0.5rem; color: #6b7280;">2026-02-08</td>
<td style="padding: 0.35rem 0;">Initial public release</td>
</tr>
</table>
</div>
<div class="alert info">
<strong><i class="fas fa-info-circle"></i> Maritime Operations Tool</strong><br>
WindMar is a physics-based vessel performance modeling system with weather-aware A* route optimization,
fuel consumption minimization, and IMO CII compliance tracking. It combines hydrodynamic resistance
calculations, seakeeping analysis, and real-time weather data to find the safest and most fuel-efficient
routes for merchant ships.
</div>
<h3>What is WindMar?</h3>
<p>
WindMar is an end-to-end maritime route optimization platform designed for Medium Range (MR) product
tankers. It models the complete chain of vessel performance physics — from calm water resistance
through wind and wave added resistance, engine SFOC curves, and propulsion efficiency — to
predict fuel consumption under real weather conditions. The A* pathfinding algorithm then searches
for the route that minimizes total fuel consumption while respecting safety constraints and regulatory
zones. All calculations are grounded in established naval architecture methods: Holtrop-Mennen for
hull resistance, Blendermann for wind loads, Kwon for wave added resistance, and simplified strip
theory for seakeeping motions.
</p>
<p>
The system ingests near-real-time wind data from NOAA GFS (0.25° resolution, via NOMADS),
wave, current, SST, swell, visibility, and ice data from Copernicus Marine Service (CMEMS).
Weather grids are pre-ingested into PostgreSQL via user-triggered resync
(wind, waves, currents, ice), with on-demand prefetch for SST, visibility, and swell — enabling sub-second route calculations.
A forecast timeline (f000–f120, 3-hourly steps) supports all 7 weather layers with play/pause and scrubbing.
The interface uses a <strong>two-mode architecture</strong>: <em>Weather mode</em> presents a full-screen ECDIS-style
chart with 7 weather overlays and WMO-standard color ramps; <em>Analysis mode</em> displays a left panel (320px) for
route import, voyage calculation, optimization comparison (A* engine with optional VISIR Dijkstra), and
Monte Carlo simulation (P10/P50/P90). A dedicated analysis page shows a per-waypoint passage plan with
ETA, SOG, wind, waves, current speed/direction, fuel, and data source badges.
The system evaluates vessel motions (roll, pitch, vertical acceleration)
and enforces safety criteria that block or penalize dangerous sea states. It calculates
the IMO Carbon Intensity Indicator (CII) rating for the completed voyage, enabling operators to
assess regulatory compliance before departure.
</p>
<div class="screenshot-gallery" style="display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin: 2rem 0;">
<figure style="margin: 0;">
<a href="assets/img/screenshots/weather-wind.png" target="_blank">
<img src="assets/img/screenshots/weather-wind.png" alt="Wind forecast with particle animation and 5-day timeline" style="width: 100%; border-radius: 8px; border: 1px solid rgba(255,255,255,0.1); box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
</a>
<figcaption style="text-align: center; font-size: 0.85rem; color: #6b7280; margin-top: 0.5rem;">
<strong>Weather Mode</strong> — GFS wind particle animation with 5-day forecast timeline and WMO color ramp
</figcaption>
</figure>
<figure style="margin: 0;">
<a href="assets/img/screenshots/route-portugal-casquets.png" target="_blank">
<img src="assets/img/screenshots/route-portugal-casquets.png" alt="Route optimization with Pareto front and strait shortcuts" style="width: 100%; border-radius: 8px; border: 1px solid rgba(255,255,255,0.1); box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
</a>
<figcaption style="text-align: center; font-size: 0.85rem; color: #6b7280; margin-top: 0.5rem;">
<strong>Route Optimization</strong> — Weather-optimal routing with Pareto front and strait shortcuts
</figcaption>
</figure>
</div>
<div class="feature-grid">
<div class="feature-card">
<h4><i class="fas fa-water"></i> Vessel Performance</h4>
<ul>
<li>Holtrop-Mennen calm water resistance</li>
<li>Blendermann wind resistance model</li>
<li>Kwon wave added resistance formula</li>
<li>Engine SFOC curves with load-dependent correction</li>
</ul>
</div>
<div class="feature-card">
<h4><i class="fas fa-route"></i> Route Optimization</h4>
<ul>
<li>A* grid search with 9 strait shortcuts (primary engine)</li>
<li>3 safety-weight variants + Pareto front (fuel vs. time)</li>
<li>Course-change penalty, safety fallback routing</li>
<li>Per-waypoint passage plan with SOG profile</li>
</ul>
</div>
<div class="feature-card">
<h4><i class="fas fa-shield-alt"></i> Seakeeping Safety</h4>
<ul>
<li>Roll, pitch, and acceleration prediction</li>
<li>Slamming probability assessment</li>
<li>Parametric roll risk detection</li>
<li>Safety constraints in route optimization</li>
</ul>
</div>
<div class="feature-card">
<h4><i class="fas fa-cloud-sun"></i> Weather Integration</h4>
<ul>
<li>7 layers: wind, waves, currents, swell, SST, visibility, ice</li>
<li>Forecast timeline for all layers (5-day, 3h steps)</li>
<li>WMO-standard color ramps per field</li>
<li>User-triggered resync + on-demand prefetch</li>
</ul>
</div>
<div class="feature-card">
<h4><i class="fas fa-certificate"></i> IMO Compliance</h4>
<ul>
<li>CII rating calculator (A through E)</li>
<li>MEPC.339(76) reference values</li>
<li>Multi-year reduction factor projections</li>
<li>CO2 emission factors for multiple fuel types</li>
</ul>
</div>
<div class="feature-card">
<h4><i class="fas fa-sliders-h"></i> Vessel Calibration</h4>
<ul>
<li>Noon report processing from Excel</li>
<li>scipy.optimize parameter fitting</li>
<li>Per-component calibration factors</li>
<li>RMSE-based objective minimization</li>
</ul>
</div>
</div>
</section>
<!-- ============================================================ -->
<!-- ARCHITECTURE -->
<!-- ============================================================ -->
<section id="architecture">
<h2>Architecture</h2>
<h3>Component Overview</h3>
<p>
WindMar follows a layered architecture with a clear separation between the user-facing frontend,
the API backend, the physics-based optimization engine, and external data providers. Each component
runs as an independent service orchestrated via Docker Compose.
</p>
<table>
<thead>
<tr>
<th>Component</th>
<th>Technology</th>
<th>Responsibility</th>
</tr>
</thead>
<tbody>
<tr>
<td>Frontend</td>
<td>Next.js 15</td>
<td>Two-mode UI (Weather/Analysis), 7 weather map layers, route analysis panel, passage plan</td>
</tr>
<tr>
<td>Backend</td>
<td>FastAPI (Python)</td>
<td>REST API, request validation, orchestration of optimization engine</td>
</tr>
<tr>
<td>Optimization Engine</td>
<td>Python (NumPy, SciPy)</td>
<td>Physics models, A* pathfinding, speed optimization, seakeeping</td>
</tr>
<tr>
<td>Weather Provider</td>
<td>NOAA GFS / CMEMS</td>
<td>GFS wind, CMEMS waves/currents/SST/swell/visibility/ice, climatology fallback, 5-day forecast</td>
</tr>
<tr>
<td>Database</td>
<td>PostgreSQL 16</td>
<td>Vessel specs, route history, calibration data, regulatory zones</td>
</tr>
<tr>
<td>Cache</td>
<td>Redis 7 / In-memory</td>
<td>Rate limiting, session state; weather fields cached in-memory</td>
</tr>
</tbody>
</table>
<h3>Data Flow</h3>
<ol>
<li><strong>Route Definition</strong> — User defines departure, arrival, and waypoints on the map interface. Vessel condition (laden/ballast) and speed preferences are selected.</li>
<li><strong>Weather Fetch</strong> — Backend requests weather data from Copernicus for the route corridor. Wind, wave, and current fields are interpolated to the optimization grid.</li>
<li><strong>Performance Calculation</strong> — For each grid cell, the optimization engine computes total resistance (calm water + wind + waves), brake power, SFOC, and fuel consumption at candidate speeds.</li>
<li><strong>A* Pathfinding</strong> — The A* algorithm searches the grid using fuel consumption as the edge cost. Safety constraints block or penalize dangerous cells. Regulatory zones modify costs.</li>
<li><strong>Speed Optimization</strong> — Each leg of the optimal path is individually speed-optimized to minimize fuel per nautical mile given local weather conditions.</li>
<li><strong>Results</strong> — The optimized route, fuel estimate, ETA, leg-by-leg breakdown, seakeeping assessment, and CII rating are returned to the frontend for display.</li>
</ol>
<h3>Docker Services</h3>
<pre><code>services:
db:
image: postgres:16-alpine
ports: ["${DB_PORT:-5432}:5432"]
redis:
image: redis:7-alpine
ports: ["${REDIS_PORT:-6379}:6379"]
api:
build: .
ports: ["${API_PORT:-8000}:8000"]
depends_on: [db, redis]
frontend:
build: ./frontend
ports: ["${FRONTEND_PORT:-3000}:3000"]
depends_on: [api]</code></pre>
<p>
All ports and credentials are configured via environment variables in <code>.env</code>
(see <code>.env.example</code> for defaults). Copy and customize before starting.
</p>
</section>
<!-- ============================================================ -->
<!-- INSTALLATION -->
<!-- ============================================================ -->
<section id="installation">
<h2>Installation</h2>
<h3>Prerequisites</h3>
<ul>
<li>Python 3.10 or later</li>
<li>Node.js 18 or later</li>
<li>Docker & Docker Compose</li>
</ul>
<h3>Docker Compose (Recommended)</h3>
<pre><code>git clone https://github.com/windmar-nav/windmar.git
cd windmar
cp .env.example .env # Edit with your settings
docker compose up -d --build</code></pre>
<p>
This starts all four services (PostgreSQL, Redis, API, frontend). By default the frontend is accessible
at <code>http://localhost:3000</code> and the backend API at <code>http://localhost:8000</code>.
Ports are configurable via <code>.env</code>.
</p>
<h3>Manual Setup</h3>
<h4>Backend</h4>
<pre><code>pip install -r requirements.txt
python api/main.py</code></pre>
<h4>Frontend</h4>
<pre><code>cd frontend
npm install --legacy-peer-deps
npm run dev</code></pre>
<h3>Weather Data Sources</h3>
<p>
WindMar uses a three-tier provider chain that automatically falls back when a source is unavailable.
See <a href="weather-data.html">Weather Data Acquisition</a> for full technical details.
</p>
<table>
<thead>
<tr><th>Data Type</th><th>Primary Source</th><th>Fallback</th><th>Credentials</th></tr>
</thead>
<tbody>
<tr><td>Wind</td><td>NOAA GFS (0.25°)</td><td>Synthetic</td><td>None (free)</td></tr>
<tr><td>Waves</td><td>CMEMS wave model</td><td>Synthetic</td><td>CMEMS account</td></tr>
<tr><td>Currents</td><td>CMEMS physics model</td><td>Synthetic</td><td>CMEMS account</td></tr>
<tr><td>Forecast</td><td>GFS f000–f120 (5-day)</td><td>—</td><td>None</td></tr>
</tbody>
</table>
<div class="alert info">
<i class="fas fa-info-circle"></i>
<strong>Wind works out of the box</strong> — GFS data from NOAA NOMADS is freely available
without authentication. Only CMEMS wave/current data requires credentials.
</div>
<h3>Obtaining Weather Credentials</h3>
<p><strong>CMEMS</strong> (waves and currents): Register at
<a href="https://marine.copernicus.eu/" target="_blank">marine.copernicus.eu</a>,
then set in <code>.env</code>:
</p>
<pre><code>COPERNICUSMARINE_SERVICE_USERNAME=your_username
COPERNICUSMARINE_SERVICE_PASSWORD=your_password</code></pre>
<p><strong>CDS ERA5</strong> (not active in v0.1.5): Code exists for ERA5 reanalysis as a wind fallback, but ingestion is disabled in this release. CDS credentials are accepted but not used.</p>
<h3>Environment Variables</h3>
<p>Copy <code>.env.example</code> to <code>.env</code> and configure. Key variables:</p>
<pre><code>DATABASE_URL=postgresql://windmar:password@db:5432/windmar
REDIS_URL=redis://:password@redis:6379/0
API_SECRET_KEY=generate_with_openssl_rand_hex_32
COPERNICUSMARINE_SERVICE_USERNAME=your_username
COPERNICUSMARINE_SERVICE_PASSWORD=your_password
CDSAPI_KEY=your_cds_personal_access_token</code></pre>
<div class="alert warning">
<strong><i class="fas fa-exclamation-triangle"></i> Security</strong><br>
Never commit <code>.env</code> to version control. The <code>.gitignore</code> excludes it by default.
See <code>.env.example</code> for all available variables with descriptions.
</div>
</section>
<!-- ============================================================ -->
<!-- TECH STACK -->
<!-- ============================================================ -->
<section id="tech-stack">
<h2>Tech Stack</h2>
<h3>Backend</h3>
<table>
<thead>
<tr><th>Library</th><th>Version</th><th>Purpose</th></tr>
</thead>
<tbody>
<tr><td>FastAPI</td><td>0.104+</td><td>REST API framework</td></tr>
<tr><td>Uvicorn</td><td>0.24+</td><td>ASGI server</td></tr>
<tr><td>SQLAlchemy</td><td>2.0+</td><td>ORM and database access</td></tr>
<tr><td>Pydantic</td><td>2.0+</td><td>Request/response validation</td></tr>
<tr><td>Alembic</td><td>1.13+</td><td>Database migrations</td></tr>
</tbody>
</table>
<h3>Frontend</h3>
<table>
<thead>
<tr><th>Library</th><th>Version</th><th>Purpose</th></tr>
</thead>
<tbody>
<tr><td>Next.js</td><td>15</td><td>React framework with SSR</td></tr>
<tr><td>React</td><td>19</td><td>UI component library</td></tr>
<tr><td>Leaflet</td><td>1.9+</td><td>Map rendering and route display</td></tr>
<tr><td>Recharts</td><td>2.10+</td><td>Charts for fuel, CII, seakeeping data</td></tr>
<tr><td>Tailwind CSS</td><td>3.4+</td><td>Utility-first styling</td></tr>
</tbody>
</table>
<h3>Scientific Computing</h3>
<table>
<thead>
<tr><th>Library</th><th>Version</th><th>Purpose</th></tr>
</thead>
<tbody>
<tr><td>NumPy</td><td>1.26+</td><td>Array operations, vector math</td></tr>
<tr><td>SciPy</td><td>1.11+</td><td>Optimization (Nelder-Mead), interpolation</td></tr>
<tr><td>global-land-mask</td><td>1.0+</td><td>Land/ocean grid classification</td></tr>
<tr><td>xarray</td><td>2024.1+</td><td>NetCDF weather data handling</td></tr>
<tr><td>copernicusmarine</td><td>1.0+</td><td>Copernicus CMEMS API client</td></tr>
</tbody>
</table>
<h3>Database & Cache</h3>
<table>
<thead>
<tr><th>Service</th><th>Version</th><th>Purpose</th></tr>
</thead>
<tbody>
<tr><td>PostgreSQL</td><td>16</td><td>Persistent storage for vessel specs, routes, zones</td></tr>
<tr><td>Redis</td><td>7</td><td>Weather field caching, session state</td></tr>
</tbody>
</table>
<h3>External APIs</h3>
<table>
<thead>
<tr><th>Service</th><th>Data</th><th>Resolution</th></tr>
</thead>
<tbody>
<tr><td>Copernicus CMEMS</td><td>Significant wave height, wave period, wave direction</td><td>0.25 deg, 3-hourly</td></tr>
<tr><td>ERA5 Reanalysis</td><td>10m wind speed, wind direction (not active in v0.1.5)</td><td>0.25 deg, hourly</td></tr>
<tr><td>Copernicus CMEMS</td><td>Ocean current speed and direction</td><td>0.083 deg, daily</td></tr>
</tbody>
</table>
</section>
<!-- ============================================================ -->
<!-- CALM WATER RESISTANCE -->
<!-- ============================================================ -->
<section id="calm-water">
<h2>Calm Water Resistance</h2>
<p>
Calm water resistance is the foundation of all fuel consumption predictions. WindMar implements the
Holtrop-Mennen method, the industry-standard empirical approach for estimating hull resistance of
displacement vessels. The method decomposes total resistance into frictional, wave-making, and
appendage components, each derived from the vessel's principal dimensions and hull form coefficients.
</p>
<h3>Holtrop-Mennen Method</h3>
<div class="formula-block">
<div class="formula-title">Total Calm Water Resistance</div>
\[R_{\text{total}} = R_f + R_w + R_{\text{app}}\]
<div class="formula-where">
<p>Where:</p>
<ul>
<li>\(R_f\) = Frictional resistance (dominant at low Froude numbers)</li>
<li>\(R_w\) = Wave-making resistance (grows exponentially with speed)</li>
<li>\(R_{\text{app}}\) = Appendage resistance (rudder, shaft brackets, etc.)</li>
</ul>
</div>
</div>
<h3>A) Frictional Resistance (R_f)</h3>
<p>
Frictional resistance arises from the viscous shear stress between the hull surface and the surrounding
water. It dominates at service speeds typical of MR tankers (Froude number 0.12-0.18). The ITTC 1957
model-ship correlation line provides the friction coefficient, and the Holtrop form factor accounts
for the three-dimensional shape of the hull.
</p>
<div class="formula-block">
<div class="formula-title">Frictional Resistance</div>
\[R_f = \tfrac{1}{2} \cdot \rho_{sw} \cdot V^2 \cdot S \cdot C_f \cdot (1 + k_1)\]
<div class="formula-where">
<p>Where:</p>
<ul>
<li>\(\rho_{sw} = 1025 \; \text{kg/m}^3\) (seawater density)</li>
<li>\(V\) = ship speed (m/s)</li>
<li>\(S\) = wetted surface area (m²)</li>
<li>\(C_f = \frac{0.075}{(\log_{10} Re - 2)^2}\) (ITTC 1957 friction line)</li>
<li>\(Re = \frac{V \cdot L_{pp}}{\nu_{sw}}\) (Reynolds number)</li>
<li>\(\nu_{sw} = 1.19 \times 10^{-6} \; \text{m}^2\text{/s}\) (kinematic viscosity at 15°C)</li>
</ul>
</div>
</div>
<p>
At service speed of 13 knots (6.69 m/s) with L_pp = 176 m, the Reynolds number is approximately
9.9 × 10<sup>8</sup>, placing the flow firmly in the turbulent regime. The friction coefficient
C_f is then approximately 0.00148.
</p>
<h3>Form Factor (1 + k_1)</h3>
<p>
The form factor corrects the flat-plate friction coefficient for the three-dimensional hull shape.
Holtrop-Mennen provides a regression formula for tanker hull forms based on the principal dimension
ratios and block coefficient.
</p>
<div class="formula-block">
<div class="formula-title">Holtrop-Mennen Form Factor for Tankers</div>
\[k_1 = \max\!\bigl(0.1,\; 0.93 + 0.4871 \cdot \frac{B}{L_{pp}} - 0.2156 \cdot \frac{B}{T} + 0.1027 \cdot C_b\bigr)\]
<div class="formula-where">
<p>Default MR tanker values:</p>
<ul>
<li>\(B / L_{pp} = 32 / 176 = 0.182\)</li>
<li>\(B / T_{\text{laden}} = 32 / 11.8 = 2.71\)</li>
<li>\(B / T_{\text{ballast}} = 32 / 6.5 = 4.92\)</li>
<li>\(C_{b,\text{laden}} = 0.82\)</li>
<li>\(C_{b,\text{ballast}} = 0.75\)</li>
</ul>
<p>Resulting form factors:</p>
<ul>
<li>\((1 + k_1)_{\text{laden}} = 1 + 0.93 + 0.4871 \times 0.182 - 0.2156 \times 2.71 + 0.1027 \times 0.82 \approx 1.52\)</li>
<li>\((1 + k_1)_{\text{ballast}} \approx 1.35\)</li>
</ul>
</div>
</div>
<h3>B) Wave-Making Resistance (R_w)</h3>
<p>
Wave-making resistance is generated by the pressure field around the hull that creates surface waves.
For MR tankers operating at low Froude numbers (Fr < 0.2), wave-making resistance is a small
fraction of total resistance. However, it increases exponentially with speed, making it the dominant
factor limiting maximum speed.
</p>
<div class="formula-block">
<div class="formula-title">Wave-Making Resistance (simplified empirical)</div>
\[R_w = 4.0 \cdot Fr^2 \cdot R_f\]
<div class="formula-where">
<p>Where:</p>
<ul>
<li>\(Fr = \frac{V}{\sqrt{g \cdot L_{pp}}}\) (Froude number)</li>
<li>\(R_f\) = frictional resistance (including form factor)</li>
<li>\(g = 9.81 \; \text{m/s}^2\)</li>
</ul>
<p>
For tankers with \(C_b > 0.75\) at low Froude numbers (\(Fr < 0.25\)),
\(R_w\) is a small fraction of total resistance, scaling quadratically with \(Fr\).
This simplified form avoids the full Holtrop-Mennen exponential coefficients
while remaining accurate for the operational speed range of merchant vessels.
</p>
</div>
</div>
<p>
At the design speed of 13 knots, the Froude number for an MR tanker is approximately
Fr = 6.69 / sqrt(9.81 × 176) ≈ 0.161. The exponential term exp(-0.4 × 0.161<sup>-2</sup>)
is very small, confirming that wave-making resistance contributes less than 5% of total resistance
at service speed.
</p>
<h3>C) Appendage Resistance (R_app)</h3>
<p>
Appendage resistance accounts for the drag of the rudder, propeller shaft brackets, bilge keels,
and other hull appendages. For MR tankers with standard appendage configurations, this is estimated
as a fixed percentage of frictional resistance.
</p>
<div class="formula-block">
<div class="formula-title">Appendage Resistance</div>
\[R_{\text{app}} = 0.05 \times R_f \quad \text{(5\% of frictional resistance)}\]
</div>
<h3>Default MR Tanker Specifications</h3>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Laden</th>
<th>Ballast</th>
</tr>
</thead>
<tbody>
<tr><td>LOA</td><td>183.0 m</td><td>183.0 m</td></tr>
<tr><td>L_pp</td><td>176.0 m</td><td>176.0 m</td></tr>
<tr><td>Beam</td><td>32.0 m</td><td>32.0 m</td></tr>
<tr><td>Draft</td><td>11.8 m</td><td>6.5 m</td></tr>
<tr><td>Displacement</td><td>65,000 MT</td><td>20,000 MT</td></tr>
<tr><td>Block Coefficient (C_b)</td><td>0.82</td><td>0.75</td></tr>
<tr><td>Wetted Surface</td><td>7,500 m²</td><td>5,200 m²</td></tr>
<tr><td>Service Speed</td><td>13.0 kts</td><td>13.0 kts</td></tr>
<tr><td>DWT</td><td>49,000 MT</td><td>—</td></tr>
<tr><td>MCR</td><td>6,600 kW</td><td>6,600 kW</td></tr>
<tr><td>SFOC at MCR</td><td>171 g/kWh</td><td>171 g/kWh</td></tr>
</tbody>
</table>
</section>
<!-- ============================================================ -->
<!-- WIND RESISTANCE -->
<!-- ============================================================ -->
<section id="wind-resistance">
<h2>Wind Resistance</h2>
<p>
Wind resistance is computed using the Blendermann method, which models the aerodynamic forces on the
vessel's above-water structure as a function of relative wind speed, direction, and the vessel's
projected areas. The method accounts for both longitudinal (drag) and transverse (side force)
components, with the longitudinal component directly opposing forward motion and the transverse
component contributing indirectly through induced drift.
</p>
<h3>Blendermann Method</h3>
<div class="formula-block">
<div class="formula-title">Relative Wind Angle</div>
\[\theta_{\text{rel}} = \left| \left( (\text{wind\_dir} - \text{heading}) + 180 \right) \bmod 360 - 180 \right|\]
<div class="formula-where">
<p>Range: \(0°\) (head wind) to \(180°\) (following wind)</p>
</div>
</div>
<div class="formula-block">
<div class="formula-title">Longitudinal Drag Coefficient</div>
<p>Simplified Blendermann for merchant vessels:</p>
\[C_{x,\text{drag}} = 0.8 \cdot \cos(\theta_{\text{rel}})\]
<p>Only the positive (opposing) component is used: \(C_{x,\text{drag}} = \max(0,\; C_{x,\text{drag}})\).</p>
<p>Transverse coefficient:</p>
\[C_y = 0.9 \cdot |\sin(\theta_{\text{rel}})|\]
</div>
<div class="formula-block">
<div class="formula-title">Wind Forces and Total Resistance</div>
<p>Direct (longitudinal) resistance:</p>
\[R_{\text{direct}} = \max(0,\; C_{x,\text{drag}}) \cdot \tfrac{1}{2} \cdot \rho_{\text{air}} \cdot V_{\text{wind}}^2 \cdot A_{\text{frontal}}\]
<p>Drift-induced resistance (10% of transverse force):</p>
\[R_{\text{drift}} = 0.1 \cdot C_y \cdot \tfrac{1}{2} \cdot \rho_{\text{air}} \cdot V_{\text{wind}}^2 \cdot A_{\text{lateral}}\]
<p>Total wind resistance:</p>
\[R_{\text{wind}} = R_{\text{direct}} + R_{\text{drift}}\]
<div class="formula-where">
<p>Where:</p>
<ul>
<li>\(\rho_{\text{air}} = 1.225 \; \text{kg/m}^3\) (air density at 15°C, sea level)</li>
<li>\(V_{\text{wind}}\) = true wind speed (m/s)</li>
<li>\(A_{\text{frontal}}\) = projected frontal area (m²)</li>
<li>\(A_{\text{lateral}}\) = projected lateral area (m²)</li>
</ul>
</div>
</div>
<h3>Wind Projection Areas</h3>
<table>
<thead>
<tr>
<th>Area</th>
<th>Laden</th>
<th>Ballast</th>
</tr>
</thead>
<tbody>
<tr><td>Frontal (A_frontal)</td><td>450 m²</td><td>850 m²</td></tr>
<tr><td>Lateral (A_lateral)</td><td>2,100 m²</td><td>2,800 m²</td></tr>
</tbody>
</table>
<div class="alert info">
<strong><i class="fas fa-info-circle"></i> Ballast Wind Exposure</strong><br>
In ballast condition the vessel rides higher, exposing 89% more frontal area (850 vs 450 m²) and
33% more lateral area (2,800 vs 2,100 m²) to the wind. This results in significantly higher
windage forces, particularly in head wind conditions where ballast wind resistance can exceed
laden resistance by a factor of two or more.
</div>
<h3>Physical Interpretation by Wind Angle</h3>
<ul>
<li><strong>Head wind (0°)</strong> — Maximum longitudinal resistance. C_x reaches its peak value. This is the worst-case scenario for fuel consumption.</li>
<li><strong>Beam wind (90°)</strong> — Minimal longitudinal component but maximum transverse force. The 10% coupling factor from F_y captures the drift-induced resistance.</li>
<li><strong>Following wind (180°)</strong> — Minimal resistance. The wind partially assists forward motion. C_x is near zero or slightly negative (assisting).</li>
</ul>
</section>
<!-- ============================================================ -->
<!-- WAVE RESISTANCE -->
<!-- ============================================================ -->
<section id="wave-resistance">
<h2>Wave Resistance</h2>
<p>
Wave added resistance is the increase in hull resistance caused by the vessel's interaction with
ocean waves. WindMar supports two methods: STAWAVE-1 (ISO 15016, default) and the Kwon empirical
speed-loss method. The Kwon method estimates added resistance by converting percentage speed loss
into equivalent resistance using the cubic power-speed relationship.
</p>
<h3>Kwon Speed-Loss Method</h3>
<div class="formula-block">
<div class="formula-title">Base Speed Loss Coefficient</div>
\[\Delta V_{\text{base}} = 3.0 \cdot (1.7 - 0.9 \cdot C_b) \cdot \max\bigl(0.5,\; \min(1.5,\; 180 / L_{pp})\bigr)\]
<p>This gives a percentage speed loss per metre of significant wave height for head seas.
Higher \(C_b\) reduces speed loss; shorter vessels lose more speed.</p>
</div>
<div class="formula-block">
<div class="formula-title">Directional Reduction Factor</div>
<p>A stepped function of relative encounter angle \(\theta\):</p>
<table>
<thead><tr><th>Encounter Angle</th><th>\(f_{\text{dir}}\)</th></tr></thead>
<tbody>
<tr><td>0°–30° (head seas)</td><td>1.0</td></tr>
<tr><td>30°–60°</td><td>0.9</td></tr>
<tr><td>60°–90° (beam)</td><td>0.7</td></tr>
<tr><td>90°–150°</td><td>0.4</td></tr>
<tr><td>150°–180° (following)</td><td>0.2</td></tr>
</tbody>
</table>
</div>
<div class="formula-block">
<div class="formula-title">Speed Loss to Equivalent Resistance</div>
\[\Delta V_{\%} = \min\bigl(50,\; \Delta V_{\text{base}} \cdot H_s \cdot f_{\text{dir}}\bigr)\]
<p>The percentage speed loss is converted to an equivalent added resistance
using the cubic power-speed relationship (\(P \propto V^3\)):</p>
\[R_{\text{wave}} = R_{\text{calm}} \cdot 2.0 \cdot \frac{\Delta V_{\%}}{100}\]
<div class="formula-where">
<p>Where:</p>
<ul>
<li>\(H_s\) = significant wave height (m)</li>
<li>\(C_b\) = block coefficient (0.82 laden, 0.75 ballast)</li>
<li>\(L_{pp}\) = length between perpendiculars (m)</li>
<li>\(R_{\text{calm}}\) = Holtrop-Mennen calm water resistance at current speed</li>
</ul>
</div>
</div>
<p>
The Kwon method produces a quadratic dependence on wave height: doubling \(H_s\) from 2 m to 4 m
doubles the speed loss percentage, which doubles the added resistance. The stepped directional
factor ensures that head seas produce maximum added resistance while following seas retain a
residual 20% effect, reflecting the fact that even stern waves cause some added resistance
through ship-motion coupling.
</p>
<h3>Dual Wave Method (v0.0.8)</h3>
<p>
Since v0.0.8, WindMar supports two wave added resistance methods, selectable via the
<code>wave_method</code> parameter on the vessel model:
</p>
<ul>
<li><strong><code>stawave1</code></strong> (default) — ISO 15016 STAWAVE-1 method.
A simplified, internationally standardized formula that estimates wave added resistance
from significant wave height, vessel length, beam, and block coefficient. Well-suited
for sea trial corrections and regulatory compliance calculations.</li>
<li><strong><code>kwon</code></strong> — Kwon empirical method (documented above).
Estimates speed loss percentage from wave height, vessel particulars, and encounter angle.
More physically detailed directional response; well-validated for merchant vessels at service speed.</li>
</ul>
<p>
Both methods are available via the <code>POST /api/vessel/predict</code> endpoint. The active method
is reported by <code>GET /api/vessel/model-status</code>.
</p>
<p>
For a laden MR tanker in head seas with H_s = 3 m at service speed (Fr ≈ 0.161), the wave
added resistance is approximately:
</p>
<div class="formula-block">
<div class="formula-title">Example Calculation</div>
\[R_{\text{wave}} = 1.0 \times 4.5 \times 1025 \times 9.81 \times 32 \times 3^2 \times (1 + 0.161)\]
\[= 1.0 \times 4.5 \times 1025 \times 9.81 \times 32 \times 9 \times 1.161 \approx 15{,}200 \; \text{N} \approx 15.2 \; \text{kN}\]
</div>
</section>
<!-- ============================================================ -->
<!-- SFOC CURVE -->
<!-- ============================================================ -->
<section id="sfoc-curve">
<h2>SFOC Curve</h2>
<p>
Specific Fuel Oil Consumption (SFOC) describes the mass of fuel consumed per unit of energy delivered
by the engine. It varies with engine load: marine diesel engines have an optimal efficiency zone
around 75% of Maximum Continuous Rating (MCR), with increasing specific consumption at both lower
and higher loads. WindMar models this behavior with a piecewise linear correction applied to the
MCR reference SFOC.
</p>
<div class="formula-block">
<div class="formula-title">SFOC Load Correction</div>
<p>Below optimal load (\(l_f < 0.75\)):</p>
\[\text{SFOC} = \text{SFOC}_{MCR} \times \bigl(1.0 + 0.15 \times (0.75 - l_f)\bigr)\]
<p>At or above optimal load (\(l_f \ge 0.75\)):</p>
\[\text{SFOC} = \text{SFOC}_{MCR} \times \bigl(1.0 + 0.05 \times (l_f - 0.75)\bigr)\]
<div class="formula-where">
<p>Constraints:</p>
<ul>
<li>\(l_f = \max\bigl(0.15,\; \min(1.0,\; P_{\text{brake}} / P_{MCR})\bigr)\)</li>
<li>\(\text{SFOC}_{MCR} = 171 \; \text{g/kWh}\) (manufacturer specification)</li>
</ul>
</div>
</div>
<p>
The asymmetric correction reflects the physical reality of diesel engine combustion: at low loads,
incomplete combustion and thermal losses increase specific consumption more steeply (15% penalty
per 0.1 load fraction below 75%) than the mild increase at high loads (5% penalty per 0.1 above 75%)
caused by increased cylinder pressures and thermal stress.
</p>
<h3>SFOC Behavior by Engine Load</h3>
<table>
<thead>
<tr>
<th>Engine Load</th>
<th>SFOC (g/kWh)</th>
<th>Efficiency Note</th>
</tr>
</thead>
<tbody>
<tr><td>15% (minimum)</td><td>~186</td><td>Minimum load limit; high specific consumption</td></tr>
<tr><td>50%</td><td>~177</td><td>Part-load penalty; below optimal range</td></tr>
<tr><td>75%</td><td>~171</td><td>Optimal operating point; minimum SFOC</td></tr>
<tr><td>85%</td><td>~172</td><td>Near optimal; slight overload penalty</td></tr>