diff --git a/docs/source/examples/example_2_wake_comparison.rst b/docs/source/examples/example_2_wake_comparison.rst
new file mode 100644
index 0000000000000000000000000000000000000000..dd8b2e2cdf9f4d6055a21458cd1d140c0d5d15c2
--- /dev/null
+++ b/docs/source/examples/example_2_wake_comparison.rst
@@ -0,0 +1,56 @@
+.. Example 2
+
+Example 2: Optimization with Different Wake Models
+===================================================
+
+This example demonstrates the optimization of a 3-turbine farm with
+the N. O. Jensen (NOJ) and G. C. Larsen (GCL) wake models implemented in
+FUSED-Wake.
+
+Specifications
+--------------
+
+- The farm is offshore.  
+- The wind resource is defined by arrays of the frequency and Weibull
+  A and k parameters taken from a Horns Rev calculation.  
+- There is a boundary beyond which the turbines cannot go.  
+- The turbines cannot be closer than 2D.
+
+Results
+-------
+
+The optimization results are visualized in the figure below, and the
+script also outputs the following information on the resultings costs::
+
+   Comparison of cost models vs. optimized locations:
+   
+   Cost    |    GCL_aep      NOJ_aep
+   ---------------------------------
+   GCL_loc |   -2704.40    -2688.57   (0.59%)
+   NOJ_loc |   -2703.90    -2688.59   (0.57%)
+                (0.02%)     (-0.00%)
+
+The subscript ``_aep`` indicates the AEP calculated using the specified wake
+model. The subscript ``_loc`` indicates the optimal locations determined when
+optimizing with the specified wake model. For example, the cost corresponding
+to the ``GCL_aep`` column and the ``NOJ_loc`` column is the AEP calculated
+using the GCL wake model for the optimal location results when the N. O.
+Jensen wake model was used in the optimization. The percentages in parentheses
+are the percent differences for the column or row.  
+
+Important observations:  
+
+- The upper and lower turbines are pushed away from each other, towards
+  the corners.  
+- There is little difference in the AEP value when calculated using either of
+  the optimal locations, since the optimal locations themselves are quite
+  close.  
+- The N. O. Jensen wake model has an AEP that is approximately 0.6% lower than
+  the AEP with the G. C. Larsen wake model for this farm.  
+
+.. figure:: /../../examples/example_2_wake_comparison.png
+
+Code
+----
+
+.. literalinclude:: /../../examples/example_2_wake_comparison.py
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 7757c90e4a5f4f9838493c86e5294421d2aa4080..b6edc02de16d8303d51950fd5c2c120d3408c668 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -16,3 +16,4 @@ Welcome to TOPFARM, the wind-farm optimizer
     :maxdepth: 2
 
     examples/example_1_constrained_layout_optimization
+    examples/example_2_wake_comparison
diff --git a/examples/example_2_wake_comparison.png b/examples/example_2_wake_comparison.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf916cb9f311d27821d60d6b3c2ad49756fd2f2c
Binary files /dev/null and b/examples/example_2_wake_comparison.png differ
diff --git a/examples/example_2_wake_comparison.py b/examples/example_2_wake_comparison.py
new file mode 100644
index 0000000000000000000000000000000000000000..4ce725c0994adf1f70a095a15c82773227850cf9
--- /dev/null
+++ b/examples/example_2_wake_comparison.py
@@ -0,0 +1,130 @@
+"""Example: optimization with different wake models
+
+This example uses a dummy cost function to optimize a simple wind turbine
+layout that is subject to constraints. The optimization pushes the wind turbine
+locations to specified locations in the farm.
+"""
+import os
+import warnings
+
+from matplotlib.patches import Polygon
+import matplotlib.pyplot as plt
+import numpy as np
+
+from topfarm.plotting import PlotComp
+from topfarm import TopFarm
+from topfarm.cost_models.utils.wind_resource import WindResource
+from topfarm.cost_models.cost_model_wrappers import AEPCostModelComponent
+from topfarm.cost_models.fused_wake_wrappers import FusedWakeGCLWakeModel, \
+    FusedWakeNOJWakeModel
+from topfarm.cost_models.utils.aep_calculator import AEPCalculator
+
+
+# ------------------------ INPUTS ------------------------
+
+# paths to input files
+test_files_dir = os.path.join(os.path.dirname(__file__), '..', 'topfarm',
+                              'tests', 'test_files')  # file locations
+wf_path = os.path.join(test_files_dir, 'wind_farms',
+                       '3tb.yml')  # path to wind farm
+f = [3.597152, 3.948682, 5.167395, 7.000154, 8.364547, 6.43485, 8.643194,
+     11.77051, 15.15757, 14.73792, 10.01205, 5.165975]  # horns rev
+a = [9.176929,  9.782334, 9.531809, 9.909545, 10.04269, 9.593921, 9.584007,
+     10.51499, 11.39895, 11.68746, 11.63732, 10.08803]  # horns rev
+k = [2.392578, 2.447266, 2.412109, 2.591797, 2.755859, 2.595703, 2.583984,
+     2.548828, 2.470703, 2.607422, 2.626953, 2.326172]  # horns rev
+rot_diam = 80.0  # rotor diameter [m]
+bnd_size = 2 * rot_diam + 10  # boundary size
+init_pos = np.array([(0, 2 * rot_diam), (0, 0),
+                     (0, -2 * rot_diam)])  # initial turbine positions
+boundary = [(-bnd_size, bnd_size), (bnd_size, bnd_size),
+            (bnd_size, -bnd_size), (-bnd_size, -bnd_size),
+            (-bnd_size, bnd_size)]  # wind farm boundary
+min_spacing = 2.0 * rot_diam  # minimum spacing between turbines [m]
+
+# ------------------------ DEFINE WIND RESOURCE ------------------------
+
+wind_res = WindResource(f, a, k, np.zeros_like(k))
+
+# ------------------------ OPTIMIZATION ------------------------
+
+warnings.filterwarnings('ignore')  # temporarily disable fusedwake warnings
+
+# GCL: define the wake model, aep calculator, and optimization problem
+wake_mod_gcl = FusedWakeGCLWakeModel(wf_path)
+aep_calc_gcl = AEPCalculator(wind_res, wake_mod_gcl)
+tf_gcl = TopFarm(init_pos, aep_calc_gcl.get_TopFarm_cost_component(),
+                 min_spacing, boundary=boundary)
+
+# NOJ: define the wake model, aep calculator, and optimization problem
+wake_mod_noj = FusedWakeNOJWakeModel(wf_path)
+aep_calc_noj = AEPCalculator(wind_res, wake_mod_noj)
+tf_noj = TopFarm(init_pos, aep_calc_noj.get_TopFarm_cost_component(),
+                 min_spacing, boundary=boundary)
+
+# run the optimization
+cost_gcl, state_gcl, recorder_gcl = tf_gcl.optimize()
+cost_noj, state_noj, recorder_noj = tf_noj.optimize()
+
+# ------------------------ POST-PROCESS ------------------------
+
+# get the optimized locations
+opt_gcl = tf_gcl.turbine_positions
+opt_noj = tf_noj.turbine_positions
+
+# create the array of costs for easier printing
+costs = np.diag([cost_gcl, cost_noj])
+costs[0, 1] = TopFarm(opt_gcl, aep_calc_noj.get_TopFarm_cost_component(),
+                      min_spacing,
+                      boundary=boundary).evaluate()[0]  # noj cost, gcl locs
+costs[1, 0] = TopFarm(opt_noj, aep_calc_gcl.get_TopFarm_cost_component(),
+                      min_spacing,
+                      boundary=boundary).evaluate()[0]  # gcl cost, noj locs
+
+warnings.filterwarnings('default')  # re-enable warnings warnings
+
+# ------------------------ PRINT STATS ------------------------
+
+aep_diffs = 200 * (costs[:, 0] - costs[:, 1]) / (costs[:, 0] + costs[:, 1])
+loc_diffs = 200 * (costs[0, :] - costs[1, :]) / (costs[0, :] + costs[1, :])
+
+print('\nComparison of cost models vs. optimized locations:')
+print('\nCost    |    GCL_aep      NOJ_aep')
+print('---------------------------------')
+print(f'GCL_loc |{costs[0,0]:11.2f} {costs[0,1]:11.2f}' +
+      f'   ({aep_diffs[0]:.2f}%)')
+print(f'NOJ_loc |{costs[1,0]:11.2f} {costs[1,1]:11.2f}' +
+      f'   ({aep_diffs[1]:.2f}%)')
+print(f'             ({loc_diffs[0]:.2f}%)     ({loc_diffs[1]:.2f}%)')
+
+# ------------------------ PLOT (if possible) ------------------------
+
+try:
+
+    # initialize the figure and axes
+    fig = plt.figure(1, figsize=(7, 5))
+    plt.clf()
+    ax = plt.axes()
+
+    # plot the boundary and desired locations
+    ax.add_patch(Polygon(boundary, fill=False,
+                         label='Boundary'))  # boundary
+    ax.plot(init_pos[:, 0], init_pos[:, 1], 'xk',
+            label='Initial')
+    ax.plot(opt_gcl[:, 0], opt_gcl[:, 1], 'o',
+            label='GCL')
+    ax.plot(opt_noj[:, 0], opt_noj[:, 1], '^',
+            label='NOJ')
+
+    # make a few adjustments to the plot
+    ax.autoscale_view()  # autoscale the boundary
+    plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
+               ncol=4, mode='expand', borderaxespad=0.)  # add a legend
+    plt.tight_layout()  # zoom the plot in
+    plt.axis('off')  # remove the axis
+
+    # save the png
+    fig.savefig(os.path.basename(__file__).replace('.py', '.png'))
+
+except RuntimeError:
+    pass