diff --git a/py_wake/deflection_models/jimenez.py b/py_wake/deflection_models/jimenez.py
index bd7fe01f4b6af47460621faf8df94a03af36849d..a8f4b525db43e1082c5fabf364c13f68e8206255 100644
--- a/py_wake/deflection_models/jimenez.py
+++ b/py_wake/deflection_models/jimenez.py
@@ -9,22 +9,25 @@ class JimenezWakeDeflection(DeflectionModel):
     the wake deflection of a wind turbine in yaw. Wind Energ., 13: 559-572. doi:10.1002/we.380
     """
 
-    args4deflection = ['D_src_il', 'yaw_ilk', 'ct_ilk']
+    args4deflection = ['D_src_il', 'yaw_ilk', 'ct_ilk', 'tilt_ilk']
 
     def __init__(self, N=20, beta=.1):
         self.beta = beta
         self.N = N
 
-    def calc_deflection(self, dw_ijl, hcw_ijl, dh_ijl, D_src_il, yaw_ilk, ct_ilk, **kwargs):
+    def calc_deflection(self, dw_ijl, hcw_ijl, dh_ijl, D_src_il, yaw_ilk, tilt_ilk, ct_ilk, **kwargs):
         dw_lst = (np.logspace(0, 1.1, self.N) - 1) / (10**1.1 - 1)
         dw_ijxl = dw_ijl[:, :, na] * dw_lst[na, na, :, na]
-        theta_ilk = np.deg2rad(yaw_ilk)
+        theta_yaw_ilk, theta_tilt_ilk = np.deg2rad(yaw_ilk), np.deg2rad(-tilt_ilk)
+        theta_ilk = np.sqrt(theta_yaw_ilk**2 + theta_tilt_ilk**2)
+        theta_deflection_ilk = np.arctan2(theta_tilt_ilk, theta_yaw_ilk)
         denominator_ilk = np.cos(theta_ilk)**2 * np.sin(theta_ilk) * (ct_ilk / 2)
         nominator_ijxl = (1 + (self.beta / D_src_il)[:, na, na, :] * dw_ijxl)**2
         alpha = denominator_ilk[:, na, na] / nominator_ijxl[..., na]
         deflection_ijlk = np.trapz(np.sin(alpha), dw_ijxl[..., na], axis=2)
-        self.hcw_ijlk = hcw_ijl[..., na] + deflection_ijlk
-        return dw_ijl[..., na], self.hcw_ijlk, dh_ijl[..., na]
+        self.hcw_ijlk = hcw_ijl[..., na] + deflection_ijlk * np.cos(theta_deflection_ilk[..., na])
+        self.dh_ijlk = dh_ijl[..., na] + deflection_ijlk * np.sin(theta_deflection_ilk[..., na])
+        return dw_ijl[..., na], self.hcw_ijlk, self.dh_ijlk
 
 
 def main():
diff --git a/py_wake/flow_map.py b/py_wake/flow_map.py
index 4d2915e0072cc7dbce25120374a4e4706f9acd37..d038bba728bc9be60b2ffc503615170f3518f964 100644
--- a/py_wake/flow_map.py
+++ b/py_wake/flow_map.py
@@ -174,14 +174,15 @@ class FlowMap(FlowBox):
     def plot_windturbines(self, normalize_with=1, ax=None):
         fm = self.windFarmModel
         yaw = self.simulationResult.yaw.sel(wd=self.wd[0]).mean(['ws']).data
+        tilt = self.simulationResult.tilt.sel(wd=self.wd[0]).mean(['ws']).data
         if self.plane[0] == "YZ":
             x_i, y_i = self.simulationResult.x.values, self.simulationResult.y.values
             h_i = self.simulationResult.h.values
             z_i = self.simulationResult.windFarmModel.site.elevation(x_i, y_i)
-            fm.windTurbines.plot_yz(y_i, z_i, h_i, wd=self.wd, yaw=yaw, normalize_with=normalize_with, ax=ax)
+            fm.windTurbines.plot_yz(y_i, z_i, h_i, wd=self.wd, yaw=yaw, tilt=tilt, normalize_with=normalize_with, ax=ax)
         else:  # self.plane[0] == "XY":
             fm.windTurbines.plot_xy(self.simulationResult.x, self.simulationResult.y, self.simulationResult.type.data,
-                                    wd=self.wd, yaw=yaw, normalize_with=normalize_with, ax=ax)
+                                    wd=self.wd, yaw=yaw, tilt=tilt, normalize_with=normalize_with, ax=ax)
 
     def plot_wake_map(self, levels=100, cmap=None, plot_colorbar=True, plot_windturbines=True,
                       normalize_with=1, ax=None):
diff --git a/py_wake/tests/test_deflection_models/test_jimenez.py b/py_wake/tests/test_deflection_models/test_jimenez.py
new file mode 100644
index 0000000000000000000000000000000000000000..62ed1913070ed076769f47b9e345fbb2aa7d4bab
--- /dev/null
+++ b/py_wake/tests/test_deflection_models/test_jimenez.py
@@ -0,0 +1,41 @@
+from py_wake.deficit_models.gaussian import IEA37SimpleBastankhahGaussian
+from py_wake.examples.data.hornsrev1 import V80
+from py_wake.examples.data.iea37._iea37 import IEA37Site
+from py_wake.deflection_models.jimenez import JimenezWakeDeflection
+from py_wake.flow_map import YZGrid, XYGrid, Points
+import matplotlib.pyplot as plt
+import numpy as np
+import pytest
+from py_wake.tests import npt
+
+
+@pytest.mark.parametrize('yaw,tilt,cx,cz', [
+    (30, 0, -30, 70),
+    (0, 30, 0, 100),
+    (29.5805, 5, -30, 75)])
+def test_yaw_tilt(yaw, tilt, cx, cz):
+    site = IEA37Site(16)
+    x, y = [0], [0]
+    windTurbines = V80()
+
+    D = windTurbines.diameter()
+    wfm = IEA37SimpleBastankhahGaussian(site, windTurbines, deflectionModel=JimenezWakeDeflection())
+    x_lst = np.linspace(-200, 1000, 100)
+    y_lst = np.linspace(-100, 100, 201)
+    z_lst = np.arange(10, 200, 1)
+
+    fm_yz = wfm(x, y, wd=270, ws=10, yaw=yaw, tilt=tilt).flow_map(YZGrid(x=5 * D, y=y_lst, z=z_lst))
+    fm_xz = wfm(x, y, wd=180, ws=10, yaw=yaw, tilt=tilt).flow_map(YZGrid(x=0, y=x_lst, z=z_lst))
+    fm_xy = wfm(x, y, wd=270, ws=10, yaw=yaw, tilt=tilt).flow_map(XYGrid(x=x_lst))
+    if 0:
+        axes = plt.subplots(3, 1)[1].flatten()
+        fm_xy.plot_wake_map(ax=axes[0])
+        axes[0].axvline(5 * D)
+        fm_xz.plot_wake_map(ax=axes[1])
+        axes[1].axvline(5 * D)
+        fm_yz.plot_wake_map(ax=axes[2])
+        plt.show()
+
+    wake_center = fm_yz.WS_eff.where(fm_yz.WS_eff == fm_yz.WS_eff.min(), drop=True).squeeze()
+    npt.assert_allclose(wake_center.y, cx, atol=.1)
+    npt.assert_allclose(wake_center.h, cz, atol=.24)
diff --git a/py_wake/tests/test_wind_farm_models/test_enginering_wind_farm_model.py b/py_wake/tests/test_wind_farm_models/test_enginering_wind_farm_model.py
index 8c6ac2c4b7f2a6e08015bc13544747fbecbe8cd3..ee131fbea11837ab56b6731c5426d9713f2de247 100644
--- a/py_wake/tests/test_wind_farm_models/test_enginering_wind_farm_model.py
+++ b/py_wake/tests/test_wind_farm_models/test_enginering_wind_farm_model.py
@@ -7,7 +7,7 @@ from py_wake.site._site import UniformSite
 from py_wake.tests import npt
 from py_wake.examples.data.hornsrev1 import HornsrevV80, Hornsrev1Site, wt_x, wt_y, V80
 from py_wake.tests.test_files.fuga import LUT_path_2MW_z0_0_03
-from py_wake.flow_map import HorizontalGrid
+from py_wake.flow_map import HorizontalGrid, XYGrid
 from py_wake.wind_farm_models.engineering_models import All2AllIterative, PropagateDownwind
 from py_wake.deficit_models.noj import NOJDeficit
 from py_wake.superposition_models import SquaredSum, WeightedSum
@@ -173,7 +173,10 @@ def test_All2AllIterativeDeflection():
                                 wake_deficitModel=NOJDeficit(),
                                 superpositionModel=SquaredSum(),
                                 deflectionModel=JimenezWakeDeflection())
-    wf_model([0], [0])
+    sim_res = wf_model([0, 500], [0, 0], wd=270, ws=10, yaw=30)
+    if 0:
+        sim_res.flow_map(XYGrid(x=np.linspace(-200, 1000, 100))).plot_wake_map()
+        plt.show()
 
 
 def test_dAEP_2wt():
diff --git a/py_wake/tests/test_windturbines/test_power_ct_curves.py b/py_wake/tests/test_windturbines/test_power_ct_curves.py
index 9b2f7f9e0061f10e9e86a8dbdf95fa11cc1255a0..b4bf0f388ca37a667931109514479860cb8e2d3b 100644
--- a/py_wake/tests/test_windturbines/test_power_ct_curves.py
+++ b/py_wake/tests/test_windturbines/test_power_ct_curves.py
@@ -30,7 +30,7 @@ def test_TabularPowerCtCurve(method, unit, p_scale, p_ref, ct_ref):
     u_ct, ct = hornsrev1.ct_curve.T
     npt.assert_array_equal(u_p, u_ct)
     curve = PowerCtTabular(ws=u_p, power=p, power_unit=unit, ct=ct, ws_cutin=4, ws_cutout=25, method=method)
-    npt.assert_array_equal(curve.optional_inputs, ['Air_density', 'yaw'])
+    npt.assert_array_equal(curve.optional_inputs, ['Air_density', 'tilt', 'yaw'])
     npt.assert_array_equal(curve.required_inputs, [])
 
     u = np.arange(0, 30, .1)
@@ -61,7 +61,7 @@ def test_MultiPowerCtCurve():
     curve = PowerCtFunctionList('mode', [PowerCtTabular(ws=u_p, power=p, power_unit='w', ct=ct),
                                          PowerCtTabular(ws=u_p, power=p * 1.1, power_unit='w', ct=ct + .1)])
 
-    npt.assert_array_equal(sorted(curve.optional_inputs), ['Air_density', 'yaw'])
+    npt.assert_array_equal(sorted(curve.optional_inputs), ['Air_density', 'tilt', 'yaw'])
     npt.assert_array_equal(list(curve.required_inputs), ['mode'])
 
     u = np.arange(0, 30, .1)
@@ -98,7 +98,7 @@ def test_MultiMultiPowerCtCurve_subset():
                                      PowerCtTabular(ws=u_p, power=p + 6, power_unit='w', ct=ct)]),
     ])
 
-    npt.assert_array_equal(sorted(curve.optional_inputs)[::-1], ['yaw', 'Air_density'])
+    npt.assert_array_equal(sorted(curve.optional_inputs)[::-1], ['yaw', 'tilt', 'Air_density'])
     npt.assert_array_equal(sorted(curve.required_inputs)[::-1], ['type', 'mode'])
 
     u = np.zeros((2, 3, 4)) + np.arange(3, 7)[na, na, :]
@@ -125,7 +125,7 @@ def test_2d_tabular():
     curve = PowerCtNDTabular(['ws', 'boost'], [u_p, [0, 1]],
                              np.array([p_c, 2 * p_c]).T, 'w',
                              np.array([ct_c, ct_c]).T)
-    npt.assert_array_equal(sorted(curve.optional_inputs)[::-1], ['yaw', 'Air_density'])
+    npt.assert_array_equal(sorted(curve.optional_inputs)[::-1], ['yaw', 'tilt', 'Air_density'])
     npt.assert_array_equal(sorted(curve.required_inputs)[::-1], ['boost'])
 
     u = np.linspace(3, 25, 10)
@@ -175,7 +175,7 @@ def test_2d_tabular_default_value():
 
 def test_FunctionalPowerCtCurve():
     curve = CubePowerSimpleCt()
-    npt.assert_array_equal(sorted(curve.optional_inputs)[::-1], ['yaw', 'Air_density'])
+    npt.assert_array_equal(sorted(curve.optional_inputs)[::-1], ['yaw', 'tilt', 'Air_density'])
     npt.assert_array_equal(curve.required_inputs, [])
     u = np.arange(0, 30, .1)
     p, ct = curve(u, Air_density=1.3)
diff --git a/py_wake/tests/test_windturbines/test_power_ct_wind_turbines.py b/py_wake/tests/test_windturbines/test_power_ct_wind_turbines.py
index 1f5373fafffa903929be52c78e45aad69621119a..a7d03f79f8572fe911b3fe6c7acd51516ccebdce 100644
--- a/py_wake/tests/test_windturbines/test_power_ct_wind_turbines.py
+++ b/py_wake/tests/test_windturbines/test_power_ct_wind_turbines.py
@@ -58,7 +58,7 @@ def test_PowerCtTabular(method, unit, p_scale, p_ref, ct_ref):
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, [])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
     sim_res = wfm([0], [0], ws=u, wd=[0]).squeeze()
     p = sim_res.Power.values
     ct = sim_res.CT.values
@@ -89,7 +89,7 @@ def test_MultiPowerCtCurve():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['mode'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     sim_res = wfm([0], [0], ws=u, wd=0, mode=0)
     p0, ct0 = sim_res.Power.squeeze().values, sim_res.CT.squeeze().values,
@@ -126,7 +126,7 @@ def test_MultiMultiPowerCtCurve_subset():
     wfm = get_wfm(curves)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['mode', 'mytype'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     u = np.zeros((2, 3, 4)) + np.arange(3, 7)[na, na, :]
     type_2 = np.array([0, 1])
@@ -157,7 +157,7 @@ def test_2d_tabular():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['boost'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     sim_res = wfm([0], [0], wd=0, ws=u, boost=0)
     p = sim_res.Power.values
@@ -198,7 +198,7 @@ def test_PowerCtXr():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['boost'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     sim_res = wfm([0], [0], wd=0, ws=u, boost=0)
     p = sim_res.Power.values
@@ -232,7 +232,7 @@ def test_FunctionalPowerCtCurve():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, [])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     u = np.arange(0, 30, .1)
     sim_res = wfm([0], [0], wd=0, ws=u)
@@ -261,7 +261,7 @@ def test_continuous():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, [])
-    npt.assert_array_equal(oi, ['Air_density', 'boost', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'boost', 'tilt', 'yaw'])
 
     u = np.arange(0, 30, .1)
     sim_res = wfm([0], [0], wd=0, ws=u)
@@ -294,7 +294,7 @@ def test_unused_input():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, [])
-    npt.assert_array_equal(oi, ['Air_density', 'boost', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'boost', 'tilt', 'yaw'])
     with pytest.raises(TypeError, match=r"got unexpected keyword argument\(s\): 'mode'"):
         wfm([0], [0], boost=1, mode=1)
 
@@ -304,7 +304,7 @@ def test_missing_input():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['boost'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     with pytest.raises(KeyError, match="Argument, boost, required to calculate power and ct not found"):
         wfm([0], [0])
@@ -319,7 +319,7 @@ def test_missing_input_PowerCtFunctionList():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['mode'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     with pytest.raises(KeyError, match="Argument, mode, required to calculate power and ct not found"):
         wfm([0], [0])
@@ -332,7 +332,7 @@ def test_DensityScaleAndSimpleYawModel():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, [])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
 
     u = np.arange(4, 25, 1.1)
     yaw = 30
@@ -378,7 +378,7 @@ def test_WSFromLocalWind():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['WD'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
     u = np.arange(4, 25, .1)
     sim_res = wfm([0], [0], wd=[2], ws=u)
     p = sim_res.Power.values.squeeze()
@@ -398,7 +398,7 @@ def test_TIFromWFM():
     wfm = get_wfm(curve)
     ri, oi = wfm.windTurbines.function_inputs
     npt.assert_array_equal(ri, ['TI_eff'])
-    npt.assert_array_equal(oi, ['Air_density', 'yaw'])
+    npt.assert_array_equal(oi, ['Air_density', 'tilt', 'yaw'])
     u = np.arange(4, 25, .1)
     with pytest.raises(KeyError, match='Argument, TI_eff, needed to calculate power and ct requires a TurbulenceModel'):
         wfm([0], [0], wd=[2], ws=u)
diff --git a/py_wake/utils/model_utils.py b/py_wake/utils/model_utils.py
index a2f593c9391928f665f6d25567dbdb038028759a..702767f8baf89ca76d2562d135dbe6d906dc2ea0 100644
--- a/py_wake/utils/model_utils.py
+++ b/py_wake/utils/model_utils.py
@@ -113,7 +113,7 @@ def get_signature(cls, kwargs={}, indent_level=0):
         return "%s(%s)" % (cls.__name__, arg_str)
 
 
-def get_model_input(wfm, x, y, ws=10, wd=270, yaw=[[[0]]]):
+def get_model_input(wfm, x, y, ws=10, wd=270, yaw=[[[0]]], tilt=[[[0]]]):
     ws, wd = [np.atleast_1d(v) for v in [ws, wd]]
     x, y = map(np.asarray, [x, y])
     wfm.site.distance.setup(src_x_i=[0], src_y_i=[0], src_h_i=[0],
@@ -124,6 +124,7 @@ def get_model_input(wfm, x, y, ws=10, wd=270, yaw=[[[0]]]):
     args = {'dw_ijl': dw_ijl, 'hcw_ijl': hcw_ijl, 'dh_ijl': dh_ijl,
             'D_src_il': np.atleast_1d(wfm.windTurbines.diameter())[na]}
     args.update({k: sim_res[n].ilk() for k, n in [('yaw_ilk', 'yaw'),
+                                                  ('tilt_ilk', 'tilt'),
                                                   ('WS_ilk', 'WS'),
                                                   ('WS_eff_ilk', 'WS_eff'),
                                                   ('ct_ilk', 'CT')]})
diff --git a/py_wake/wind_farm_models/engineering_models.py b/py_wake/wind_farm_models/engineering_models.py
index 98e2dd75199cd57ba9be4fe8d15d4afb8d40d054..7e975e1f3964226fd721ad39b1ca37e952690b39 100644
--- a/py_wake/wind_farm_models/engineering_models.py
+++ b/py_wake/wind_farm_models/engineering_models.py
@@ -150,7 +150,8 @@ class EngineeringWindFarmModel(WindFarmModel):
         deficit, blockage = self._add_blockage(deficit, dw_ijlk, **kwargs)
         return deficit, uc, sigma_sqr, blockage
 
-    def calc_wt_interaction(self, x_i, y_i, h_i=None, type_i=0, wd=None, ws=None, time=False, yaw_ilk=None, **kwargs):
+    def calc_wt_interaction(self, x_i, y_i, h_i=None, type_i=0, wd=None, ws=None, time=False,
+                            yaw_ilk=None, tilt_ilk=None, **kwargs):
         """See WindFarmModel.calc_wt_interaction"""
         h_i, D_i = self.windTurbines.get_defaults(len(x_i), type_i, h_i)
         x_i, y_i, type_i = [np.asarray(v) for v in [x_i, y_i, type_i]]
@@ -200,8 +201,8 @@ class EngineeringWindFarmModel(WindFarmModel):
         def add_arg(name, optional):
             if name in wt_kwargs:  # custom WindFarmModel.__call__ arguments
                 return
-            elif name in {'yaw', 'type'}:  # fixed WindFarmModel.__call__ arguments
-                wt_kwargs[name] = {'yaw': yaw_ilk, 'type': type_i}[name]
+            elif name in {'yaw', 'tilt', 'type'}:  # fixed WindFarmModel.__call__ arguments
+                wt_kwargs[name] = {'yaw': yaw_ilk, 'tilt': tilt_ilk, 'type': type_i}[name]
             elif name in lw:
                 wt_kwargs[name] = lw[name].values
             elif name in self.site.ds:
@@ -223,10 +224,13 @@ class EngineeringWindFarmModel(WindFarmModel):
 
         if yaw_ilk is None:
             yaw_ilk = np.zeros((I, L, K))
+        if tilt_ilk is None:
+            tilt_ilk = np.zeros((I, L, K))
 
         kwargs = {'localWind': lw,
                   'WS_eff_ilk': WS_eff_ilk, 'TI_eff_ilk': TI_eff_ilk,
-                  'x_i': x_i, 'y_i': y_i, 'h_i': h_i, 'D_i': D_i, 'yaw_ilk': yaw_ilk,
+                  'x_i': x_i, 'y_i': y_i, 'h_i': h_i, 'D_i': D_i,
+                  'yaw_ilk': yaw_ilk, 'tilt_ilk': tilt_ilk,
                   'I': I, 'L': L, 'K': K, **wt_kwargs}
         WS_eff_ilk, TI_eff_ilk, ct_ilk = self._calc_wt_interaction(**kwargs)
         if 'TI_eff' in wt_kwargs:
@@ -281,6 +285,7 @@ class EngineeringWindFarmModel(WindFarmModel):
                          'TI_ilk': get_ilk('TI'),
                          'TI_eff_ilk': get_ilk('TI_eff'),
                          'yaw_ilk': get_ilk('yaw'),
+                         'tilt_ilk': get_ilk('tilt'),
                          'D_src_il': lambda: wt_d_i[:, na],
                          'D_dst_ijl': lambda: np.zeros_like(dh_ijl),
                          'h_il': lambda: wt_h_i.data[:, na],
@@ -291,7 +296,7 @@ class EngineeringWindFarmModel(WindFarmModel):
                     ** {k: arg_funcs[k]() for k in self.deflectionModel.args4deflection})
             else:
                 dw_ijlk, hcw_ijlk, dh_ijlk = dw_ijl[..., na], hcw_ijl[..., na], dh_ijl[..., na]
-            arg_funcs.update({'cw_ijlk': lambda: np.hypot(dh_ijl[..., na], hcw_ijlk),
+            arg_funcs.update({'cw_ijlk': lambda: np.hypot(dh_ijlk, hcw_ijlk),
                               'dw_ijlk': lambda: dw_ijlk, 'hcw_ijlk': lambda: hcw_ijlk, 'dh_ijlk': lambda: dh_ijlk})
 
             args = {k: arg_funcs[k]() for k in self.args4deficit if k != 'dw_ijlk'}
@@ -414,7 +419,7 @@ class PropagateDownwind(EngineeringWindFarmModel):
 
     def _calc_wt_interaction(self, localWind,
                              WS_eff_ilk, TI_eff_ilk,
-                             x_i, y_i, h_i, D_i, yaw_ilk,
+                             x_i, y_i, h_i, D_i, yaw_ilk, tilt_ilk,
                              I, L, K, **kwargs):
         """
         Additional suffixes:
@@ -441,6 +446,7 @@ class PropagateDownwind(EngineeringWindFarmModel):
         WS_eff_mk = []
         TI_eff_mk = []
         yaw_mk = ilk2mk(yaw_ilk)
+        tilt_mk = ilk2mk(tilt_ilk)
         ct_jlk = []
 
         if self.turbulenceModel:
@@ -517,6 +523,7 @@ class PropagateDownwind(EngineeringWindFarmModel):
                              'TI_eff_ilk': lambda: TI_eff_mk[-1][na],
                              'D_src_il': lambda: D_i[i_wt_l][na],
                              'yaw_ilk': lambda: yaw_mk[m][na],
+                             'tilt_ilk': lambda: tilt_mk[m][na],
                              'D_dst_ijl': lambda: D_i[dw_order_indices_dl[:, j + 1:]].T[na],
                              'h_il': lambda: h_i[i_wt_l][na],
                              'ct_ilk': lambda: ct_lk[na],
@@ -621,8 +628,7 @@ class All2AllIterative(EngineeringWindFarmModel):
 
     def _calc_wt_interaction(self, localWind,
                              WS_eff_ilk, TI_eff_ilk,
-                             x_i, y_i, h_i, D_i, yaw_ilk,
-                             # dw_iil, hcw_iil, cw_iil, dh_iil, dw_order_indices_dl,
+                             x_i, y_i, h_i, D_i, yaw_ilk, tilt_ilk,
                              I, L, K, **kwargs):
         lw = localWind
         WS_eff_ilk_last = WS_eff_ilk.copy()
@@ -634,6 +640,7 @@ class All2AllIterative(EngineeringWindFarmModel):
                 'TI_ilk': lw.TI.ilk((I, L, K)),
                 'TI_eff_ilk': lw.TI.ilk((I, L, K)),
                 'yaw_ilk': yaw_ilk,
+                'tilt_ilk': tilt_ilk,
                 'D_src_il': D_src_il,
                 'D_dst_ijl': D_src_il[na],
                 'cw_ijlk': np.sqrt(hcw_iil**2 + dh_iil**2)[..., na],
@@ -649,7 +656,7 @@ class All2AllIterative(EngineeringWindFarmModel):
             args['WS_eff_ilk'] = WS_eff_ilk
             if self.deflectionModel:
                 dw_ijlk, hcw_ijlk, dh_ijlk = self.deflectionModel.calc_deflection(
-                    dw_ijl=dw_iil, hcw_ijl=dw_iil, dh_ijl=dh_iil, **args)
+                    dw_ijl=dw_iil, hcw_ijl=hcw_iil, dh_ijl=dh_iil, **args)
                 args.update({'dw_ijlk': dw_ijlk, 'hcw_ijlk': hcw_ijlk, 'dh_ijlk': dh_ijlk,
                              'cw_ijlk': np.hypot(dh_iil[..., na], hcw_ijlk)})
             else:
diff --git a/py_wake/wind_farm_models/wind_farm_model.py b/py_wake/wind_farm_models/wind_farm_model.py
index 41a9ada8eefbd51e39f43941b1b92ccca3459dbd..26963921b2436437fc3fc4d4a3ac1b06d2d2c2f9 100644
--- a/py_wake/wind_farm_models/wind_farm_model.py
+++ b/py_wake/wind_farm_models/wind_farm_model.py
@@ -19,7 +19,8 @@ class WindFarmModel(ABC):
         self.site = site
         self.windTurbines = windTurbines
 
-    def __call__(self, x, y, h=None, type=0, wd=None, ws=None, yaw=None, time=False, verbose=False, **kwargs):
+    def __call__(self, x, y, h=None, type=0, wd=None, ws=None, yaw=None,
+                 tilt=None, time=False, verbose=False, **kwargs):
         """Run the wind farm simulation
 
         Parameters
@@ -54,18 +55,20 @@ class WindFarmModel(ABC):
             raise ValueError(
                 'Custom *yaw*-keyword arguments not allowed to avoid confusion with the default "yaw" keyword')
         yaw_ilk = fix_shape(yaw, (I, L, K), allow_None=True)
+        tilt_ilk = fix_shape(tilt, (I, L, K), allow_None=True)
 
         if len(x) == 0:
             lw = UniformSite([1], 0.1).local_wind(x_i=[], y_i=[], h_i=[], wd=wd, ws=ws)
             z = xr.DataArray(np.zeros((0, len(lw.wd), len(lw.ws))), coords=[('wt', []), ('wd', lw.wd), ('ws', lw.ws)])
-            return SimulationResult(self, lw, [], yaw, z, z, z, z, kwargs)
-        res = self.calc_wt_interaction(x_i=np.asarray(x), y_i=np.asarray(y), h_i=h, type_i=type, yaw_ilk=yaw_ilk,
+            return SimulationResult(self, lw, [], yaw, tilt, z, z, z, z, kwargs)
+        res = self.calc_wt_interaction(x_i=np.asarray(x), y_i=np.asarray(y), h_i=h, type_i=type,
+                                       yaw_ilk=yaw_ilk, tilt_ilk=tilt_ilk,
                                        wd=wd, ws=ws, time=time, **kwargs)
         WS_eff_ilk, TI_eff_ilk, power_ilk, ct_ilk, localWind, wt_inputs = res
 
         return SimulationResult(self, localWind=localWind,
-                                type_i=np.zeros(len(x), dtype=int) + type, yaw_ilk=yaw_ilk,
-
+                                type_i=np.zeros(len(x), dtype=int) + type,
+                                yaw_ilk=yaw_ilk, tilt_ilk=tilt_ilk,
                                 WS_eff_ilk=WS_eff_ilk, TI_eff_ilk=TI_eff_ilk,
                                 power_ilk=power_ilk, ct_ilk=ct_ilk, wt_inputs=wt_inputs)
 
@@ -146,7 +149,7 @@ class SimulationResult(xr.Dataset):
     """Simulation result returned when calling a WindFarmModel object"""
     __slots__ = ('windFarmModel', 'localWind', 'wt_inputs')
 
-    def __init__(self, windFarmModel, localWind, type_i, yaw_ilk,
+    def __init__(self, windFarmModel, localWind, type_i, yaw_ilk, tilt_ilk,
                  WS_eff_ilk, TI_eff_ilk, power_ilk, ct_ilk, wt_inputs):
         self.windFarmModel = windFarmModel
         lw = localWind
@@ -187,6 +190,11 @@ class SimulationResult(xr.Dataset):
         else:
             self.add_ilk('yaw', yaw_ilk)
         self['yaw'].attrs['Description'] = 'Yaw misalignment [deg]'
+        if tilt_ilk is None:
+            self['tilt'] = self.Power * 0
+        else:
+            self.add_ilk('tilt', tilt_ilk)
+        self['tilt'].attrs['Description'] = 'Rotor tilt [deg]'
 
         # for backward compatibility
         for k in ['WD', 'WS', 'TI', 'P', 'WS_eff', 'TI_eff']:
@@ -245,7 +253,7 @@ class SimulationResult(xr.Dataset):
                 self.Weibull_k.ilk())
             aep = weighted_power * self.Sector_frequency.ilk() * hours_pr_year * 1e-9
             ws = (self.ws.values[1:] + self.ws.values[:-1]) / 2
-            return xr.DataArray(aep, [('wt', self.wt), ('wd', self.wd), ('ws', ws)])
+            return xr.DataArray(aep, [('wt', self.wt.values), ('wd', self.wd.values), ('ws', ws)])
         else:
             weighted_power = power_ilk * self.P.ilk() / norm
         if 'time' in self and weighted_power.shape[2] == 1:
@@ -423,7 +431,7 @@ class SimulationResult(xr.Dataset):
         ds = xr.load_dataset(filename)
         lw = LocalWind(ds.x, ds.y, ds.h, ds.wd, ds.ws, time=False, wd_bin_size=ds.attrs['wd_bin_size'],
                        WD=ds.WD, WS=ds.WS, TI=ds.TI, P=ds.P)
-        sim_res = SimulationResult(wfm, lw, type_i=ds.type.values, yaw_ilk=ds.yaw,
+        sim_res = SimulationResult(wfm, lw, type_i=ds.type.values, yaw_ilk=ds.yaw, tilt_ilk=ds.tilt,
                                    WS_eff_ilk=ds.WS_eff.ilk(), TI_eff_ilk=ds.TI_eff.ilk(), power_ilk=ds.Power, ct_ilk=ds.CT,
                                    wt_inputs={})
 
diff --git a/py_wake/wind_turbines/_wind_turbines.py b/py_wake/wind_turbines/_wind_turbines.py
index 35fdb9d70bbb00c7d5235043c4566d9aa0130685..09d3f8220db690ea41b9155559aa32009a7eae51 100644
--- a/py_wake/wind_turbines/_wind_turbines.py
+++ b/py_wake/wind_turbines/_wind_turbines.py
@@ -128,7 +128,7 @@ Use WindTurbines(names, diameters, hub_heights, power_ct_funcs) instead""", Depr
     def enable_autograd(self):
         self.powerCtFunction.enable_autograd()
 
-    def plot_xy(self, x, y, types=None, wd=None, yaw=0, normalize_with=1, ax=None):
+    def plot_xy(self, x, y, types=None, wd=None, yaw=0, tilt=0, normalize_with=1, ax=None):
         """Plot wind farm layout including type name and diameter
 
         Parameters
@@ -158,6 +158,7 @@ Use WindTurbines(names, diameters, hub_heights, power_ct_funcs) instead""", Depr
         assert len(x) == len(y)
         types = (np.zeros_like(x) + types).astype(int)  # ensure same length as x
         yaw = np.zeros_like(x) + yaw
+        tilt = np.zeros_like(x) + tilt
 
         x, y, D = [np.asarray(v) / normalize_with for v in [x, y, self.diameter(types)]]
         R = D / 2
@@ -168,8 +169,9 @@ Use WindTurbines(names, diameters, hub_heights, power_ct_funcs) instead""", Depr
                 ax.plot(x_, y_, 'None', )
             else:
                 for wd_ in np.atleast_1d(wd):
-                    c, s = np.cos(np.deg2rad(90 + wd_ - yaw_)), np.sin(np.deg2rad(90 + wd_ - yaw_))
-                    ax.plot([x_ - s * r, x_ + s * r], [y_ - c * r, y_ + c * r], lw=1, color=colors[t])
+                    circle = Ellipse((x_, y), 2 * r * np.sin(np.deg2rad(tilt)), 2 * r,
+                                     angle=90 - wd_ + yaw_, ec=colors[t], fc="None")
+                    ax.add_artist(circle)
 
         for t, m, c in zip(np.unique(types), markers, colors):
             # ax.plot(np.asarray(x)[types == t], np.asarray(y)[types == t], '%sk' % m, label=self._names[int(t)])
@@ -180,7 +182,7 @@ Use WindTurbines(names, diameters, hub_heights, power_ct_funcs) instead""", Depr
         ax.legend(loc=1)
         ax.axis('equal')
 
-    def plot_yz(self, y, z=None, h=None, types=None, wd=270, yaw=0, normalize_with=1, ax=None):
+    def plot_yz(self, y, z=None, h=None, types=None, wd=270, yaw=0, tilt=0, normalize_with=1, ax=None):
         """Plot wind farm layout in yz-plane including type name and diameter
 
         Parameters
@@ -216,10 +218,12 @@ Use WindTurbines(names, diameters, hub_heights, power_ct_funcs) instead""", Depr
         from matplotlib.patches import Circle
 
         yaw = np.zeros_like(y) + yaw
+        tilt = np.zeros_like(y) + tilt
         y, z, h, D = [v / normalize_with for v in [y, z, h, self.diameter(types)]]
         for i, (y_, z_, h_, d, t, yaw_) in enumerate(
                 zip(y, z, h, D, types, yaw)):
-            circle = Ellipse((y_, h_ + z_), d * np.sin(np.deg2rad(wd - yaw_)), d, ec=colors[t], fc="None")
+            circle = Ellipse((y_, h_ + z_), d * np.sin(np.deg2rad(wd - yaw_)),
+                             d, angle=-tilt, ec=colors[t], fc="None")
             ax.add_artist(circle)
             ax.plot([y_, y_], [z_, z_ + h_], 'k')
             ax.plot(y_, h_, 'None')
@@ -232,8 +236,8 @@ Use WindTurbines(names, diameters, hub_heights, power_ct_funcs) instead""", Depr
         ax.legend(loc=1)
         ax.axis('equal')
 
-    def plot(self, x, y, type=None, wd=None, yaw=0, normalize_with=1, ax=None):
-        return self.plot_xy(x, y, type, wd, yaw, normalize_with, ax)
+    def plot(self, x, y, type=None, wd=None, yaw=0, tilt=0, normalize_with=1, ax=None):
+        return self.plot_xy(x, y, type, wd, yaw, tilt, normalize_with, ax)
 
     @staticmethod
     def from_WindTurbine_lst(wt_lst):
diff --git a/py_wake/wind_turbines/power_ct_functions.py b/py_wake/wind_turbines/power_ct_functions.py
index fcca9caa6c4276df914083caf59a2699cdfe72ce..c6cd9aee40194593112db2460a381bba7357266f 100644
--- a/py_wake/wind_turbines/power_ct_functions.py
+++ b/py_wake/wind_turbines/power_ct_functions.py
@@ -98,11 +98,18 @@ class SimpleYawModel(AdditionalModel):
     """Simple model that replace ws with cos(yaw)*ws and scales the CT output with cos(yaw)**2"""
 
     def __init__(self):
-        AdditionalModel.__init__(self, input_keys=['ws', 'yaw'], optional_inputs=['yaw'], output_keys=['power', 'ct'])
-
-    def __call__(self, f, ws, yaw=None, **kwargs):
-        if yaw is not None:
-            co = np.cos(np.deg2rad(fix_shape(yaw, ws, True)))
+        AdditionalModel.__init__(
+            self, input_keys=[
+                'ws', 'yaw', 'tilt'], optional_inputs=['yaw', 'tilt'],
+            output_keys=['power', 'ct'])
+
+    def __call__(self, f, ws, yaw=None, tilt=None, **kwargs):
+        if yaw is not None or tilt is not None:
+            co = 1
+            if yaw is not None:
+                co *= np.cos(np.deg2rad(fix_shape(yaw, ws, True)))
+            if tilt is not None:
+                co *= np.cos(np.deg2rad(fix_shape(tilt, ws, True)))
             power_ct_arr = f(ws * co, **kwargs)  # calculate for reduced ws (ws projection on rotor)
             if kwargs['run_only'] == 1:  # ct
                 # multiply ct by cos(yaw)**2 to compensate for reduced thrust