diff --git a/examples/IsothermalPotential/GravityOnly/externalGravity.yml b/examples/IsothermalPotential/GravityOnly/externalGravity.yml
new file mode 100644
index 0000000000000000000000000000000000000000..53c8a0cf20a0fd9666b5f9fb43baeff6045ce978
--- /dev/null
+++ b/examples/IsothermalPotential/GravityOnly/externalGravity.yml
@@ -0,0 +1,73 @@
+# Define the system of units to use internally. 
+InternalUnitSystem:
+  UnitMass_in_cgs:     1.9885e33     # Grams
+  UnitLength_in_cgs:   3.0856776e21  # Centimeters
+  UnitVelocity_in_cgs: 1e5           # Centimeters per second
+  UnitCurrent_in_cgs:  1   # Amperes
+  UnitTemp_in_cgs:     1   # Kelvin
+
+# Parameters governing the time integration
+TimeIntegration:
+  time_begin: 0.    # The starting time of the simulation (in internal units).
+  time_end:   8.    # The end time of the simulation (in internal units).
+  dt_min:     1e-7  # The minimal time-step size of the simulation (in internal units).
+  dt_max:     1e-1  # The maximal time-step size of the simulation (in internal units).
+
+# Parameters governing the conserved quantities statistics
+Statistics:
+  delta_time:          1e-2 # Time between statistics output
+  
+# Parameters governing the snapshots
+Snapshots:
+  basename:            Isothermal # Common part of the name of output files
+  time_first:          0.        # Time of the first output (in internal units)
+  delta_time:          0.02      # Time difference between consecutive outputs (in internal units)
+
+# Parameters for the task scheduling
+Scheduler:
+  nr_threads:       8        # The number of threads per MPI rank to use.
+  nr_queues:        0        # The number of task queues to use. Use 0  to let the system decide.
+  cell_max_size:    8000000  # Maximal number of interactions per task (this is the default value).
+  cell_sub_size:    8000000  # Maximal number of interactions per sub-task  (this is the default value).
+  cell_split_size:  400      # Maximal number of particles per cell (this is the default value).
+
+
+# Parameters for the hydrodynamics scheme
+SPH:
+  resolution_eta:        1.2349   # Target smoothing length in units of the mean inter-particle separation (1.2349 == 48Ngbs with the cubic spline kernel).
+  delta_neighbours:      1.       # The tolerance for the targetted number of neighbours.
+  CFL_condition:         0.1      # Courant-Friedrich-Levy condition for time integration.
+  max_ghost_iterations:  30       # Maximal number of iterations allowed to converge towards the smoothing length.
+  max_smoothing_length:  40.      # Maximal smoothing length allowed (in internal units).
+
+# Parameters related to the initial conditions
+InitialConditions:
+  file_name:  Isothermal.hdf5       # The file to read
+  h_scaling:  1.                    # A scaling factor to apply to all smoothing lengths in the ICs.
+  shift_x:    100.                  # A shift to apply to all particles read from the ICs (in internal units).
+  shift_y:    100.
+  shift_z:    100.
+
+# Parameters govering domain decomposition
+DomainDecomposition:
+  initial_type:       m     # The initial strategy ("g", "m", "w", or "v"). See documentation for details.
+  initial_grid_x:    10     # Grid size if the 'g' strategy is chosen.
+  initial_grid_y:    10
+  initial_grid_z:    10
+  repartition_type:   b     # The re-decomposition strategy ("n", "b", "v", "e" or "x"). See documentation for details.
+ 
+
+# External potential parameters
+PointMass:
+	position_x:      50.     # location of external point mass in internal units
+	position_y:      50.
+	position_z:      50.	
+	mass:            1e10     # mass of external point mass in internal units
+
+IsothermalPotential:
+	position_x:      100.     # location of external point mass in internal units
+	position_y:      100.
+	position_z:      100.	
+	vrot:            200.     # rotation speed of isothermal potential in internal units
+
+
diff --git a/examples/IsothermalPotential/GravityOnly/legend.pro b/examples/IsothermalPotential/GravityOnly/legend.pro
new file mode 100755
index 0000000000000000000000000000000000000000..e510bdfcd7dcabed796cb090c6fa7d54536608b6
--- /dev/null
+++ b/examples/IsothermalPotential/GravityOnly/legend.pro
@@ -0,0 +1,459 @@
+;+
+; NAME:
+;       LEGEND
+; PURPOSE:
+;       Create an annotation legend for a plot.
+; EXPLANATION:
+;       This procedure makes a legend for a plot.  The legend can contain
+;       a mixture of symbols, linestyles, Hershey characters (vectorfont),
+;       and filled polygons (usersym).  A test procedure, legendtest.pro,
+;       shows legend's capabilities.  Placement of the legend is controlled
+;       with keywords like /right, /top, and /center or by using a position
+;       keyword for exact placement (position=[x,y]) or via mouse (/position).
+; CALLING SEQUENCE:
+;       LEGEND [,items][,keyword options]
+; EXAMPLES:
+;       The call:
+;               legend,['Plus sign','Asterisk','Period'],psym=[1,2,3]
+;         produces:
+;               -----------------
+;               |               |
+;               |  + Plus sign  |
+;               |  * Asterisk   |
+;               |  . Period     |
+;               |               |
+;               -----------------
+;         Each symbol is drawn with a plots command, so they look OK.
+;         Other examples are given in optional output keywords.
+;
+;       lines = indgen(6)                       ; for line styles
+;       items = 'linestyle '+strtrim(lines,2)   ; annotations
+;       legend,items,linestyle=lines            ; vertical legend---upper left
+;       items = ['Plus sign','Asterisk','Period']
+;       sym = [1,2,3]
+;       legend,items,psym=sym                   ; ditto except using symbols
+;       legend,items,psym=sym,/horizontal       ; horizontal format
+;       legend,items,psym=sym,box=0             ; sans border
+;       legend,items,psym=sym,delimiter='='     ; embed '=' betw psym & text
+;       legend,items,psym=sym,margin=2          ; 2-character margin
+;       legend,items,psym=sym,position=[x,y]    ; upper left in data coords
+;       legend,items,psym=sym,pos=[x,y],/norm   ; upper left in normal coords
+;       legend,items,psym=sym,pos=[x,y],/device ; upper left in device coords
+;       legend,items,psym=sym,/position         ; interactive position
+;       legend,items,psym=sym,/right            ; at upper right
+;       legend,items,psym=sym,/bottom           ; at lower left
+;       legend,items,psym=sym,/center           ; approximately near center
+;       legend,items,psym=sym,number=2          ; plot two symbols, not one
+;       legend,items,/fill,psym=[8,8,8],colors=[10,20,30]; 3 filled squares
+; INPUTS:
+;       items = text for the items in the legend, a string array.
+;               For example, items = ['diamond','asterisk','square'].
+;               You can omit items if you don't want any text labels.
+; OPTIONAL INPUT KEYWORDS:
+;
+;       linestyle = array of linestyle numbers  If linestyle[i] < 0, then omit
+;               ith symbol or line to allow a multi-line entry.     If 
+;               linestyle = -99 then text will be left-justified.  
+;       psym = array of plot symbol numbers.  If psym[i] is negative, then a
+;               line connects pts for ith item.  If psym[i] = 8, then the
+;               procedure usersym is called with vertices define in the
+;               keyword usersym.   If psym[i] = 88, then use the previously
+;               defined user symbol
+;       vectorfont = vector-drawn characters for the sym/line column, e.g.,
+;               ['!9B!3','!9C!3','!9D!3'] produces an open square, a checkmark,
+;               and a partial derivative, which might have accompanying items
+;               ['BOX','CHECK','PARTIAL DERIVATIVE'].
+;               There is no check that !p.font is set properly, e.g., -1 for
+;               X and 0 for PostScript.  This can produce an error, e.g., use
+;               !20 with PostScript and !p.font=0, but allows use of Hershey
+;               *AND* PostScript fonts together.
+;       N. B.: Choose any of linestyle, psym, and/or vectorfont.  If none is
+;               present, only the text is output.  If more than one
+;               is present, all need the same number of elements, and normal
+;               plot behaviour occurs.
+;               By default, if psym is positive, you get one point so there is
+;               no connecting line.  If vectorfont[i] = '',
+;               then plots is called to make a symbol or a line, but if
+;               vectorfont[i] is a non-null string, then xyouts is called.
+;       /help = flag to print header
+;       /horizontal = flag to make the legend horizontal
+;       /vertical = flag to make the legend vertical (D=vertical)
+;       box = flag to include/omit box around the legend (D=include)
+;       clear = flag to clear the box area before drawing the legend
+;       delimiter = embedded character(s) between symbol and text (D=none)
+;       colors = array of colors for plot symbols/lines (D=!P.color)
+;       textcolors = array of colors for text (D=!P.color)
+;       margin = margin around text measured in characters and lines
+;       spacing = line spacing (D=bit more than character height)
+;       pspacing = psym spacing (D=3 characters) (when number of symbols is
+;             greater than 1)
+;       charsize = just like !p.charsize for plot labels
+;       charthick = just like !p.charthick for plot labels
+;       thick = array of line thickness numbers (D = !P.thick), if used, then 
+;               linestyle must also be specified
+;       position = data coordinates of the /top (D) /left (D) of the legend
+;       normal = use normal coordinates for position, not data
+;       device = use device coordinates for position, not data
+;       number = number of plot symbols to plot or length of line (D=1)
+;       usersym = 2-D array of vertices, cf. usersym in IDL manual. 
+;             (/USERSYM =square, default is to use existing USERSYM definition)
+;       /fill = flag to fill the usersym
+;       /left_legend = flag to place legend snug against left side of plot
+;                 window (D)
+;       /right_legend = flag to place legend snug against right side of plot
+;               window.    If /right,pos=[x,y], then x is position of RHS and
+;               text runs right-to-left.
+;       /top_legend = flag to place legend snug against top of plot window (D)
+;       /bottom = flag to place legend snug against bottom of plot window
+;               /top,pos=[x,y] and /bottom,pos=[x,y] produce same positions.
+;
+;       If LINESTYLE, PSYM, VECTORFONT, THICK, COLORS, or TEXTCOLORS are
+;       supplied as scalars, then the scalar value is set for every line or
+;       symbol in the legend.
+; Outputs:
+;       legend to current plot device
+; OPTIONAL OUTPUT KEYWORDS:
+;       corners = 4-element array, like !p.position, of the normalized
+;         coords for the box (even if box=0): [llx,lly,urx,ury].
+;         Useful for multi-column or multi-line legends, for example,
+;         to make a 2-column legend, you might do the following:
+;           c1_items = ['diamond','asterisk','square']
+;           c1_psym = [4,2,6]
+;           c2_items = ['solid','dashed','dotted']
+;           c2_line = [0,2,1]
+;           legend,c1_items,psym=c1_psym,corners=c1,box=0
+;           legend,c2_items,line=c2_line,corners=c2,box=0,pos=[c1[2],c1[3]]
+;           c = [c1[0]<c2[0],c1[1]<c2[1],c1[2]>c2[2],c1[3]>c2[3]]
+;           plots,[c[0],c[0],c[2],c[2],c[0]],[c[1],c[3],c[3],c[1],c[1]],/norm
+;         Useful also to place the legend.  Here's an automatic way to place
+;         the legend in the lower right corner.  The difficulty is that the
+;         legend's width is unknown until it is plotted.  In this example,
+;         the legend is plotted twice: the first time in the upper left, the
+;         second time in the lower right.
+;           legend,['1','22','333','4444'],linestyle=indgen(4),corners=corners
+;                       ; BOGUS LEGEND---FIRST TIME TO REPORT CORNERS
+;           xydims = [corners[2]-corners[0],corners[3]-corners[1]]
+;                       ; SAVE WIDTH AND HEIGHT
+;           chdim=[!d.x_ch_size/float(!d.x_size),!d.y_ch_size/float(!d.y_size)]
+;                       ; DIMENSIONS OF ONE CHARACTER IN NORMALIZED COORDS
+;           pos = [!x.window[1]-chdim[0]-xydims[0] $
+;                       ,!y.window[0]+chdim[1]+xydims[1]]
+;                       ; CALCULATE POSITION FOR LOWER RIGHT
+;           plot,findgen(10)    ; SIMPLE PLOT; YOU DO WHATEVER YOU WANT HERE.
+;           legend,['1','22','333','4444'],linestyle=indgen(4),pos=pos
+;                       ; REDO THE LEGEND IN LOWER RIGHT CORNER
+;         You can modify the pos calculation to place the legend where you
+;         want.  For example to place it in the upper right:
+;           pos = [!x.window[1]-chdim[0]-xydims[0],!y.window[1]-xydims[1]]
+; Common blocks:
+;       none
+; Procedure:
+;       If keyword help is set, call doc_library to print header.
+;       See notes in the code.  Much of the code deals with placement of the
+;       legend.  The main problem with placement is not being
+;       able to sense the length of a string before it is output.  Some crude
+;       approximations are used for centering.
+; Restrictions:
+;       Here are some things that aren't implemented.
+;       - An orientation keyword would allow lines at angles in the legend.
+;       - An array of usersyms would be nice---simple change.
+;       - An order option to interchange symbols and text might be nice.
+;       - Somebody might like double boxes, e.g., with box = 2.
+;       - Another feature might be a continuous bar with ticks and text.
+;       - There are no guards to avoid writing outside the plot area.
+;       - There is no provision for multi-line text, e.g., '1st line!c2nd line'
+;         Sensing !c would be easy, but !c isn't implemented for PostScript.
+;         A better way might be to simply output the 2nd line as another item
+;         but without any accompanying symbol or linestyle.  A flag to omit
+;         the symbol and linestyle is linestyle[i] = -1.
+;       - There is no ability to make a title line containing any of titles
+;         for the legend, for the symbols, or for the text.
+; Side Effects:
+; Modification history:
+;       write, 24-25 Aug 92, F K Knight (knight@ll.mit.edu)
+;       allow omission of items or omission of both psym and linestyle, add
+;         corners keyword to facilitate multi-column legends, improve place-
+;         ment of symbols and text, add guards for unequal size, 26 Aug 92, FKK
+;       add linestyle(i)=-1 to suppress a single symbol/line, 27 Aug 92, FKK
+;       add keyword vectorfont to allow characters in the sym/line column,
+;         28 Aug 92, FKK
+;       add /top, /bottom, /left, /right keywords for automatic placement at
+;         the four corners of the plot window.  The /right keyword forces
+;         right-to-left printing of menu. 18 Jun 93, FKK
+;       change default position to data coords and add normal, data, and
+;         device keywords, 17 Jan 94, FKK
+;       add /center keyword for positioning, but it is not precise because
+;         text string lengths cannot be known in advance, 17 Jan 94, FKK
+;       add interactive positioning with /position keyword, 17 Jan 94, FKK
+;       allow a legend with just text, no plotting symbols.  This helps in
+;         simply describing a plot or writing assumptions done, 4 Feb 94, FKK
+;       added thick, symsize, and clear keyword Feb 96, W. Landsman HSTX
+;               David Seed, HR Wallingford, d.seed@hrwallingford.co.uk
+;       allow scalar specification of keywords, Mar 96, W. Landsman HSTX
+;       added charthick keyword, June 96, W. Landsman HSTX
+;       Made keyword names  left,right,top,bottom,center longer,
+;                                 Aug 16, 2000, Kim Tolbert
+;       Added ability to have regular text lines in addition to plot legend 
+;       lines in legend.  If linestyle is -99 that item is left-justified.
+;       Previously, only option for no sym/line was linestyle=-1, but then text
+;       was lined up after sym/line column.    10 Oct 2000, Kim Tolbert
+;       Make default value of thick = !P.thick  W. Landsman  Jan. 2001
+;       Don't overwrite existing USERSYM definition  W. Landsman Mar. 2002
+;-
+pro legend, items, BOTTOM_LEGEND=bottom, BOX = box, CENTER_LEGEND=center, $
+    CHARTHICK=charthick, CHARSIZE = charsize, CLEAR = clear, COLORS = colorsi, $
+    CORNERS = corners, DATA=data, DELIMITER=delimiter, DEVICE=device, $
+    FILL=fill, HELP = help, HORIZONTAL=horizontal,LEFT_LEGEND=left, $
+    LINESTYLE=linestylei, MARGIN=margin, NORMAL=normal, NUMBER=number, $
+    POSITION=position,PSPACING=pspacing, PSYM=psymi, RIGHT_LEGEND=right, $
+    SPACING=spacing, SYMSIZE=symsize, TEXTCOLORS=textcolorsi, THICK=thicki, $
+    TOP_LEGEND=top, USERSYM=usersym,  VECTORFONT=vectorfonti, VERTICAL=vertical
+;
+;       =====>> HELP
+;
+on_error,2
+if keyword_set(help) then begin & doc_library,'legend' & return & endif
+;
+;       =====>> SET DEFAULTS FOR SYMBOLS, LINESTYLES, AND ITEMS.
+;
+ ni = n_elements(items)
+ np = n_elements(psymi)
+ nl = n_elements(linestylei)
+ nth = n_elements(thicki)
+ nv = n_elements(vectorfonti)
+ nlpv = max([np,nl,nv])
+ n = max([ni,np,nl,nv])                                  ; NUMBER OF ENTRIES
+strn = strtrim(n,2)                                     ; FOR ERROR MESSAGES
+if n eq 0 then message,'No inputs!  For help, type legend,/help.'
+if ni eq 0 then begin
+  items = replicate('',n)                               ; DEFAULT BLANK ARRAY
+endif else begin
+  if size(items,/TNAME) NE 'STRING' then message, $
+      'First parameter must be a string array.  For help, type legend,/help.'
+  if ni ne n then message,'Must have number of items equal to '+strn
+endelse
+symline = (np ne 0) or (nl ne 0)                        ; FLAG TO PLOT SYM/LINE
+ if (np ne 0) and (np ne n) and (np NE 1) then message, $
+        'Must have 0, 1 or '+strn+' elements in PSYM array.'
+ if (nl ne 0) and (nl ne n) and (nl NE 1) then message, $
+         'Must have 0, 1 or '+strn+' elements in LINESTYLE array.'
+ if (nth ne 0) and (nth ne n) and (nth NE 1) then message, $
+         'Must have 0, 1 or '+strn+' elements in THICK array.'
+
+ case nl of 
+ 0: linestyle = intarr(n)              ;Default = solid
+ 1: linestyle = intarr(n)  + linestylei
+ else: linestyle = linestylei
+ endcase 
+ 
+ case nth of 
+ 0: thick = replicate(!p.thick,n)      ;Default = !P.THICK
+ 1: thick = intarr(n) + thicki
+ else: thick = thicki
+ endcase 
+
+ case np of             ;Get symbols
+ 0: psym = intarr(n)    ;Default = solid
+ 1: psym = intarr(n) + psymi
+ else: psym = psymi
+ endcase 
+
+ case nv of 
+ 0: vectorfont = replicate('',n)
+ 1: vectorfont = replicate(vectorfonti,n)
+ else: vectorfont = vectorfonti
+ endcase 
+;
+;       =====>> CHOOSE VERTICAL OR HORIZONTAL ORIENTATION.
+;
+if n_elements(horizontal) eq 0 then begin               ; D=VERTICAL
+  if n_elements(vertical) eq 0 then vertical = 1
+endif else begin
+  if n_elements(vertical) eq 0 then vertical = not horizontal
+endelse
+;
+;       =====>> SET DEFAULTS FOR OTHER OPTIONS.
+;
+if n_elements(box) eq 0 then box = 1
+if n_elements(clear) eq 0 then clear = 0
+
+if n_elements(margin) eq 0 then margin = 0.5
+if n_elements(delimiter) eq 0 then delimiter = ''
+if n_elements(charsize) eq 0 then charsize = !p.charsize
+if n_elements(charthick) eq 0 then charthick = !p.charthick
+if charsize eq 0 then charsize = 1
+if (n_elements (symsize) eq 0) then symsize= charsize + intarr(n)
+if n_elements(number) eq 0 then number = 1
+ case N_elements(colorsi) of 
+ 0: colors = replicate(!P.color,n)     ;Default is !P.COLOR
+ 1: colors = replicate(colorsi,n)
+ else: colors = colorsi
+ endcase 
+
+ case N_elements(textcolorsi) of 
+ 0: textcolors = replicate(!P.color,n)      ;Default is !P.COLOR
+ 1: textcolors = replicate(textcolorsi,n)
+ else: textcolors = textcolorsi
+ endcase 
+ fill = keyword_set(fill)
+if n_elements(usersym) eq 1 then usersym = 2*[[0,0],[0,1],[1,1],[1,0],[0,0]]-1
+;
+;       =====>> INITIALIZE SPACING
+;
+if n_elements(spacing) eq 0 then spacing = 1.2
+if n_elements(pspacing) eq 0 then pspacing = 3
+xspacing = !d.x_ch_size/float(!d.x_size) * (spacing > charsize)
+yspacing = !d.y_ch_size/float(!d.y_size) * (spacing > charsize)
+ltor = 1                                        ; flag for left-to-right
+if n_elements(left) eq 1 then ltor = left eq 1
+if n_elements(right) eq 1 then ltor = right ne 1
+ttob = 1                                        ; flag for top-to-bottom
+if n_elements(top) eq 1 then ttob = top eq 1
+if n_elements(bottom) eq 1 then ttob = bottom ne 1
+xalign = ltor ne 1                              ; x alignment: 1 or 0
+yalign = -0.5*ttob + 1                          ; y alignment: 0.5 or 1
+xsign = 2*ltor - 1                              ; xspacing direction: 1 or -1
+ysign = 2*ttob - 1                              ; yspacing direction: 1 or -1
+if not ttob then yspacing = -yspacing
+if not ltor then xspacing = -xspacing
+;
+;       =====>> INITIALIZE POSITIONS: FIRST CALCULATE X OFFSET FOR TEXT
+;
+xt = 0
+if nlpv gt 0 then begin                         ; SKIP IF TEXT ITEMS ONLY.
+if vertical then begin                          ; CALC OFFSET FOR TEXT START
+  for i = 0,n-1 do begin
+    if (psym[i] eq 0) and (vectorfont[i] eq '') then num = (number + 1) > 3 else num = number
+    if psym[i] lt 0 then num = number > 2       ; TO SHOW CONNECTING LINE
+    if psym[i] eq 0 then expand = 1 else expand = 2
+    thisxt = (expand*pspacing*(num-1)*xspacing)
+    if ltor then xt = thisxt > xt else xt = thisxt < xt
+    endfor
+endif   ; NOW xt IS AN X OFFSET TO ALIGN ALL TEXT ENTRIES.
+endif
+;
+;       =====>> INITIALIZE POSITIONS: SECOND LOCATE BORDER
+;
+if !x.window[0] eq !x.window[1] then begin
+  plot,/nodata,xstyle=4,ystyle=4,[0],/noerase
+endif
+;       next line takes care of weirdness with small windows
+pos = [min(!x.window),min(!y.window),max(!x.window),max(!y.window)]
+case n_elements(position) of
+ 0: begin
+  if ltor then px = pos[0] else px = pos[2]
+  if ttob then py = pos[3] else py = pos[1]
+  if keyword_set(center) then begin
+    if not keyword_set(right) and not keyword_set(left) then $
+      px = (pos[0] + pos[2])/2. - xt
+    if not keyword_set(top) and not keyword_set(bottom) then $
+      py = (pos[1] + pos[3])/2. + n*yspacing
+    endif
+  position = [px,py] + [xspacing,-yspacing]
+  end
+ 1: begin       ; interactive
+  message,/inform,'Place mouse at upper left corner and click any mouse button.'
+  cursor,x,y,/normal
+  position = [x,y]
+  end
+ 2: begin       ; convert upper left corner to normal coordinates
+  if keyword_set(data) then $
+    position = convert_coord(position,/to_norm) $
+  else if keyword_set(device) then $
+    position = convert_coord(position,/to_norm,/device) $
+  else if not keyword_set(normal) then $
+    position = convert_coord(position,/to_norm)
+  end
+ else: message,'Position keyword can have 0, 1, or 2 elements only. Try legend,/help.'
+endcase
+
+yoff = 0.25*yspacing*ysign                      ; VERT. OFFSET FOR SYM/LINE.
+
+x0 = position[0] + (margin)*xspacing            ; INITIAL X & Y POSITIONS
+y0 = position[1] - margin*yspacing + yalign*yspacing    ; WELL, THIS WORKS!
+;
+;       =====>> OUTPUT TEXT FOR LEGEND, ITEM BY ITEM.
+;       =====>> FOR EACH ITEM, PLACE SYM/LINE, THEN DELIMITER,
+;       =====>> THEN TEXT---UPDATING X & Y POSITIONS EACH TIME.
+;       =====>> THERE ARE A NUMBER OF EXCEPTIONS DONE WITH IF STATEMENTS.
+;
+for iclr = 0,clear do begin
+  y = y0                                                ; STARTING X & Y POSITIONS
+  x = x0
+  if ltor then xend = 0 else xend = 1           ; SAVED WIDTH FOR DRAWING BOX
+
+ if ttob then ii = [0,n-1,1] else ii = [n-1,0,-1]
+ for i = ii[0],ii[1],ii[2] do begin
+  if vertical then x = x0 else y = y0           ; RESET EITHER X OR Y
+  x = x + xspacing                              ; UPDATE X & Y POSITIONS
+  y = y - yspacing
+  if nlpv eq 0 then goto,TEXT_ONLY              ; FLAG FOR TEXT ONLY
+  if (psym[i] eq 0) and (vectorfont[i] eq '') then num = (number + 1) > 3 else num = number
+  if psym[i] lt 0 then num = number > 2         ; TO SHOW CONNECTING LINE
+  if psym[i] eq 0 then expand = 1 else expand = 2
+  xp = x + expand*pspacing*indgen(num)*xspacing
+  if (psym[i] gt 0) and (num eq 1) and vertical then xp = x + xt/2.
+  yp = y + intarr(num)
+  if vectorfont[i] eq '' then yp = yp + yoff
+  if psym[i] eq 0 then begin
+    xp = [min(xp),max(xp)]                      ; TO EXPOSE LINESTYLES
+    yp = [min(yp),max(yp)]                      ; DITTO
+    endif
+  if (psym[i] eq 8) and (N_elements(usersym) GT 1) then $
+                usersym,usersym,fill=fill,color=colors[i]
+;; extra by djseed .. psym=88 means use the already defined usersymbol
+ if psym[i] eq 88 then psym[i] =8
+  if vectorfont[i] ne '' then begin
+;    if (num eq 1) and vertical then xp = x + xt/2      ; IF 1, CENTERED.
+    xyouts,xp,yp,vectorfont[i],width=width,color=colors[i] $
+      ,size=charsize,align=xalign,charthick = charthick,/norm
+    xt = xt > width
+    xp = xp + width/2.
+  endif else begin
+    if symline and (linestyle[i] ge 0) then plots,xp,yp,color=colors[i] $
+      ,/normal,linestyle=linestyle[i],psym=psym[i],symsize=symsize[i], $
+      thick=thick[i]
+  endelse
+
+  if vertical then x = x + xt else if ltor then x = max(xp) else x = min(xp)
+  if symline then x = x + xspacing
+  TEXT_ONLY:
+  if vertical and (vectorfont[i] eq '') and symline and (linestyle[i] eq -99) then x=x0 + xspacing
+  xyouts,x,y,delimiter,width=width,/norm,color=textcolors[i], $
+         size=charsize,align=xalign,charthick = charthick
+  x = x + width*xsign
+  if width ne 0 then x = x + 0.5*xspacing
+  xyouts,x,y,items[i],width=width,/norm,color=textcolors[i],size=charsize, $
+             align=xalign,charthick=charthick
+  x = x + width*xsign
+  if not vertical and (i lt (n-1)) then x = x+2*xspacing; ADD INTER-ITEM SPACE
+  xfinal = (x + xspacing*margin)
+  if ltor then xend = xfinal > xend else xend = xfinal < xend   ; UPDATE END X
+ endfor
+
+ if (iclr lt clear ) then begin
+;       =====>> CLEAR AREA
+        x = position[0]
+        y = position[1]
+        if vertical then bottom = n else bottom = 1
+        ywidth = - (2*margin+bottom-0.5)*yspacing
+        corners = [x,y+ywidth,xend,y]
+        polyfill,[x,xend,xend,x,x],y + [0,0,ywidth,ywidth,0],/norm,color=-1
+;       plots,[x,xend,xend,x,x],y + [0,0,ywidth,ywidth,0],thick=2
+ endif else begin
+
+;
+;       =====>> OUTPUT BORDER
+;
+        x = position[0]
+        y = position[1]
+        if vertical then bottom = n else bottom = 1
+        ywidth = - (2*margin+bottom-0.5)*yspacing
+        corners = [x,y+ywidth,xend,y]
+        if box then plots,[x,xend,xend,x,x],y + [0,0,ywidth,ywidth,0],/norm
+        return
+ endelse
+endfor
+
+end
+
diff --git a/examples/IsothermalPotential/GravityOnly/makeIC.py b/examples/IsothermalPotential/GravityOnly/makeIC.py
new file mode 100644
index 0000000000000000000000000000000000000000..88115668bd11e19f93765860540dcf33c6ae5c64
--- /dev/null
+++ b/examples/IsothermalPotential/GravityOnly/makeIC.py
@@ -0,0 +1,168 @@
+###############################################################################
+ # This file is part of SWIFT.
+ # Copyright (c) 2016 John A. Regan (john.a.regan@durham.ac.uk)
+ #                    Tom Theuns (tom.theuns@durham.ac.uk)
+ # 
+ # This program is free software: you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published
+ # by the Free Software Foundation, either version 3 of the License, or
+ # (at your option) any later version.
+ # 
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ # 
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ # 
+ ##############################################################################
+
+import h5py
+import sys
+import numpy
+import math
+import random
+
+# Generates N particles in a spherical distribution centred on [0,0,0], to be moved in an isothermal potential
+# usage: python makeIC.py 1000 0 : generate 1000 particles on circular orbits
+#        python makeIC.py 1000 1 : generate 1000 particles with Lz/L uniform in [0,1]
+# all particles move in the xy plane, and start at y=0
+
+# physical constants in cgs
+NEWTON_GRAVITY_CGS  = 6.672e-8
+SOLAR_MASS_IN_CGS   = 1.9885e33
+PARSEC_IN_CGS       = 3.0856776e18
+PROTON_MASS_IN_CGS  = 1.6726231e24
+YEAR_IN_CGS         = 3.154e+7
+
+# choice of units
+const_unit_length_in_cgs   =   (1000*PARSEC_IN_CGS)
+const_unit_mass_in_cgs     =   (SOLAR_MASS_IN_CGS)
+const_unit_velocity_in_cgs =   (1e5)
+
+print "UnitMass_in_cgs:     ", const_unit_mass_in_cgs 
+print "UnitLength_in_cgs:   ", const_unit_length_in_cgs
+print "UnitVelocity_in_cgs: ", const_unit_velocity_in_cgs
+
+
+# rotation speed of isothermal potential [km/s]
+vrot_kms = 200.
+
+# derived units
+const_unit_time_in_cgs = (const_unit_length_in_cgs / const_unit_velocity_in_cgs)
+const_G                = ((NEWTON_GRAVITY_CGS*const_unit_mass_in_cgs*const_unit_time_in_cgs*const_unit_time_in_cgs/(const_unit_length_in_cgs*const_unit_length_in_cgs*const_unit_length_in_cgs)))
+print 'G=', const_G
+vrot   = vrot_kms * 1e5 / const_unit_velocity_in_cgs
+
+
+# Parameters
+periodic= 1            # 1 For periodic box
+boxSize = 400.         #  [kpc]
+Radius  = 100.          # maximum radius of particles [kpc]
+G       = const_G 
+
+N       = int(sys.argv[1])  # Number of particles
+icirc   = int(sys.argv[2])  # if = 0, all particles are on circular orbits, if = 1, Lz/Lcirc uniform in ]0,1[
+L       = N**(1./3.)
+
+# these are not used but necessary for I/O
+rho = 2.              # Density
+P = 1.                # Pressure
+gamma = 5./3.         # Gas adiabatic index
+fileName = "Isothermal.hdf5" 
+
+
+#---------------------------------------------------
+numPart        = N
+mass           = 1
+internalEnergy = P / ((gamma - 1.)*rho)
+
+#--------------------------------------------------
+
+#File
+file = h5py.File(fileName, 'w')
+
+#Units
+grp = file.create_group("/Units")
+grp.attrs["Unit length in cgs (U_L)"] = const_unit_length_in_cgs
+grp.attrs["Unit mass in cgs (U_M)"] = const_unit_mass_in_cgs 
+grp.attrs["Unit time in cgs (U_t)"] = const_unit_length_in_cgs / const_unit_velocity_in_cgs
+grp.attrs["Unit current in cgs (U_I)"] = 1.
+grp.attrs["Unit temperature in cgs (U_T)"] = 1.
+
+# Header
+grp = file.create_group("/Header")
+grp.attrs["BoxSize"] = boxSize
+grp.attrs["NumPart_Total"] =  [0, numPart, 0, 0, 0, 0]
+grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
+grp.attrs["NumPart_ThisFile"] = [0, numPart, 0, 0, 0, 0]
+grp.attrs["Time"] = 0.0
+grp.attrs["NumFilesPerSnapshot"] = 1
+grp.attrs["MassTable"] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
+grp.attrs["Flag_Entropy_ICs"] = [0, 0, 0, 0, 0, 0]
+
+
+#Runtime parameters
+grp = file.create_group("/RuntimePars")
+grp.attrs["PeriodicBoundariesOn"] = periodic
+
+# set seed for random number
+numpy.random.seed(1234)
+
+#Particle group
+#grp0 = file.create_group("/PartType0")
+grp1 = file.create_group("/PartType1")
+#generate particle positions
+radius = Radius * (numpy.random.rand(N))**(1./3.) 
+ctheta = -1. + 2 * numpy.random.rand(N)
+stheta = numpy.sqrt(1.-ctheta**2)
+phi    =  2 * math.pi * numpy.random.rand(N)
+r      = numpy.zeros((numPart, 3))
+#r[:,0] = radius * stheta * numpy.cos(phi)
+#r[:,1] = radius * stheta * numpy.sin(phi)
+#r[:,2] = radius * ctheta
+r[:,0] = radius
+#
+speed  = vrot
+v      = numpy.zeros((numPart, 3))
+omega  = speed / radius
+period = 2.*math.pi/omega
+print 'period = minimum = ',min(period), ' maximum = ',max(period)
+
+omegav = omega
+if (icirc != 0):
+    omegav = omega * numpy.random.rand(N)
+
+v[:,0] = -omegav * r[:,1]
+v[:,1] =  omegav * r[:,0]
+
+ds = grp1.create_dataset('Velocities', (numPart, 3), 'f')
+ds[()] = v
+v = numpy.zeros(1)
+
+m = numpy.full((numPart, ), mass)
+ds = grp1.create_dataset('Masses', (numPart,), 'f')
+ds[()] = m
+m = numpy.zeros(1)
+
+h = numpy.full((numPart, ), 1.1255 * boxSize / L)
+ds = grp1.create_dataset('SmoothingLength', (numPart,), 'f')
+ds[()] = h
+h = numpy.zeros(1)
+
+u = numpy.full((numPart, ), internalEnergy)
+ds = grp1.create_dataset('InternalEnergy', (numPart,), 'f')
+ds[()] = u
+u = numpy.zeros(1)
+
+
+ids = 1 + numpy.linspace(0, numPart, numPart, endpoint=False, dtype='L')
+ds = grp1.create_dataset('ParticleIDs', (numPart, ), 'L')
+ds[()] = ids
+
+ds = grp1.create_dataset('Coordinates', (numPart, 3), 'd')
+ds[()] = r
+
+
+file.close()
diff --git a/examples/IsothermalPotential/GravityOnly/readme.txt b/examples/IsothermalPotential/GravityOnly/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..90fb1872aa2301cab133b8a20a8cd8de724d4553
--- /dev/null
+++ b/examples/IsothermalPotential/GravityOnly/readme.txt
@@ -0,0 +1,6 @@
+;
+; this probelm generates a set of gravity particles in an isothermal
+; potential and follows their orbits. Tests verify consdevation of
+; energy and angular momentum
+;
+;
diff --git a/examples/IsothermalPotential/GravityOnly/run.sh b/examples/IsothermalPotential/GravityOnly/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..89e7c10ce19ce0576127551f63eea5c9e4e955ff
--- /dev/null
+++ b/examples/IsothermalPotential/GravityOnly/run.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+# Generate the initial conditions if they are not present.
+if [ ! -e Isothermal.hdf5 ]
+then
+    echo "Generating initial conditions for the point mass potential box example..."
+    python makeIC.py 1000
+fi
+
+../swift -g -t 2 externalGravity.yml
diff --git a/examples/IsothermalPotential/GravityOnly/test.pro b/examples/IsothermalPotential/GravityOnly/test.pro
new file mode 100644
index 0000000000000000000000000000000000000000..ac1f5e915c38c107408ffed9579c52944295f079
--- /dev/null
+++ b/examples/IsothermalPotential/GravityOnly/test.pro
@@ -0,0 +1,168 @@
+;
+;  test energy / angular momentum conservation of test problem
+;
+
+iplot = 1 ; if iplot = 1, make plot of E/Lz conservation, else, simply compare final and initial energy
+
+; set physical constants
+@physunits
+
+indir    = './'
+basefile = 'Isothermal_'
+
+; set properties of potential
+uL   = 1e3 * phys.pc             ; unit of length
+uM   = phys.msun                 ; unit of mass
+uV   = 1d5                       ; unit of velocity
+vrot = 200.                      ; km/s
+r200 = 100.                      ; virial radius
+
+; derived units
+constG   = 10.^(alog10(phys.g)+alog10(uM)-2d0*alog10(uV)-alog10(uL)) ;
+pcentre  = [100.,100.,100.] * 1d3 * pc / uL
+
+;
+infile = indir + basefile + '*'
+spawn,'ls -1 '+infile,res
+nfiles = n_elements(res)
+
+
+
+; choose: calculate change of energy and Lz, comparing first and last
+; snapshots for all particles, or do so for a subset
+
+; compare all
+ifile   = 0
+inf     = indir + basefile + strtrim(string(ifile,'(i3.3)'),1) + '.hdf5'
+id      = h5rd(inf,'PartType1/ParticleIDs')
+nfollow = n_elements(id)
+
+; follow a subset
+nfollow  = 500                    ; number of particles to follow
+
+;
+if (iplot eq 1) then begin
+   nskip = 1
+   nsave = nfiles
+endif else begin
+   nskip = nfiles - 2
+   nsave = 2
+endelse
+
+;
+lout     = fltarr(nfollow, nsave) ; Lz
+xout     = fltarr(nfollow, nsave) ; x
+yout     = fltarr(nfollow, nsave) ; y
+zout     = fltarr(nfollow, nsave) ; z
+eout     = fltarr(nfollow, nsave) ; energies
+ekin     = fltarr(nfollow, nsave)
+epot     = fltarr(nfollow, nsave)
+tout     = fltarr(nsave)
+
+
+
+ifile  = 0
+isave = 0
+for ifile=0,nfiles-1,nskip do begin
+   inf    = indir + basefile + strtrim(string(ifile,'(i3.3)'),1) + '.hdf5'
+   time   = h5ra(inf, 'Header','Time')
+   p      = h5rd(inf,'PartType1/Coordinates')
+   v      = h5rd(inf,'PartType1/Velocities')
+   id     = h5rd(inf,'PartType1/ParticleIDs')
+   indx   = sort(id)
+;
+   id     = id[indx]
+   for ic=0,2 do begin
+      tmp = reform(p[ic,*]) & p[ic,*] = tmp[indx]
+      tmp = reform(v[ic,*]) & v[ic,*] = tmp[indx]
+   endfor
+
+
+; calculate energy
+   dd  = size(p,/dimen) & npart = dd[1]
+   ener = fltarr(npart)
+   dr   = fltarr(npart) & dv = dr
+   for ic=0,2 do dr[*] = dr[*] + (p[ic,*]-pcentre[ic])^2
+   for ic=0,2 do dv[*] = dv[*] + v[ic,*]^2
+   xout[*,isave] = p[0,0:nfollow-1]-pcentre[0]
+   yout[*,isave] = p[1,0:nfollow-1]-pcentre[1]
+   zout[*,isave] = p[2,0:nfollow-1]-pcentre[2]
+   Lz  = (p[0,*]-pcentre[0]) * v[1,*] - (p[1,*]-pcentre[1]) * v[0,*]
+   dr = sqrt(dr)
+;   print,'time = ',time,p[0,0],v[0,0],id[0]
+   ek   = 0.5 * dv
+;   ep   = - constG * mextern / dr
+   ep   = -vrot*vrot * (1 + alog(r200/dr))
+   ener = ek + ep
+   tout(isave) = time
+   lout[*,isave] = lz[0:nfollow-1]
+   eout(*,isave) = ener[0:nfollow-1]
+   ekin(*,isave) = ek[0:nfollow-1]
+   epot(*,isave) = ep[0:nfollow-1]
+
+;  write some output
+;   print,' time= ',time,' e= ',eout[0],' Lz= ',lz[0],format='(%a %f %a
+;   %f)'
+   print,format='('' time= '',f7.1,'' E= '',f9.2,'' Lz= '',e9.2)', time,eout[0],lz[0]
+   isave = isave + 1
+   
+endfor
+x0 = reform(xout[0,*])
+y0 = reform(xout[1,*])
+z0 = reform(xout[2,*])
+
+; calculate relative energy change
+de    = 0.0 * eout
+dl    = 0.0 * lout
+nsave = isave
+for ifile=1, nsave-1 do de[*,ifile] = (eout[*,ifile]-eout[*,0])/eout[*,0]
+for ifile=1, nsave-1 do dl[*,ifile] = (lout[*,ifile] - lout[*,0])/lout[*,0]
+
+
+; calculate statistics of energy changes
+print,' relatve energy change: (per cent) ',minmax(de) * 100.
+print,' relative Lz    change: (per cent) ',minmax(dl) * 100.
+
+; plot enery and Lz conservation for some particles
+if(iplot eq 1) then begin
+; plot results on energy conservation for some particles
+   nplot = min(10, nfollow)
+   wset,0
+   xr = [min(tout), max(tout)]
+   yr = [-2,2]*1d-2             ; in percent
+   plot,[0],[0],xr=xr,yr=yr,/xs,/ys,/nodata,xtitle='time',ytitle='dE/E, dL/L (%)'
+   for i=0,nplot-1 do oplot,tout,de[i,*]
+   for i=0,nplot-1 do oplot,tout,dl[i,*],color=red
+   legend,['dE/E','dL/L'],linestyle=[0,0],color=[black,red],box=0,/bottom,/left
+   screen_to_png,'e-time.png'
+
+;  plot orbits of those particles
+   wset,2
+   xr = [-100,100]
+   yr = xr
+   plot,[0],[0],xr=xr,yr=yr,/xs,/ys,/iso,/nodata,xtitle='x',ytitle='y'
+   color = floor(findgen(nplot)*255/float(nplot))
+   for i=0,nplot-1 do oplot,xout[i,*],yout[i,*],color=color(i)
+   screen_to_png,'orbit.png'
+
+; plot radial position of these particles
+   wset,4
+   xr = [min(tout), max(tout)]
+   yr = [0,80]
+   plot,[0],[0],xr=xr,yr=yr,/xs,/ys,/nodata,xtitle='t',ytitle='r'
+   color = floor(findgen(nplot)*255/float(nplot))
+for i=0,nplot-1 do begin dr = sqrt(reform(xout[i,*])^2 + reform(yout[i,*])^2) &  oplot,tout,dr,color=color[i] & endfor
+   screen_to_png,'r-time.png'
+
+; make histogram of energy changes at end
+   wset,6
+   ohist,de,x,y,-0.05,0.05,0.001
+   plot,x,y,psym=10,xtitle='de (%)'
+   screen_to_png,'de-hist.png'
+
+
+endif
+
+end
+
+
diff --git a/src/const.h b/src/const.h
index 65404d6a3e89d85c64c81e28c6eaf9e1884c82e2..0487da30ccbd4fb7951de62a388c917b1d5510f3 100644
--- a/src/const.h
+++ b/src/const.h
@@ -60,7 +60,8 @@
 //#define DEFAULT_SPH
 
 /* Gravity properties */
-#define EXTERNAL_POTENTIAL_POINTMASS
+/* #define EXTERNAL_POTENTIAL_POINTMASS */
+#define EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
 
 /* Are we debugging ? */
 //#define SWIFT_DEBUG_CHECKS
diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h
index 7ef6db76e47f5a1cb2efee9d90fabb9f2ca7dd7f..0e4784693ad05b64e876b0b3f0f87b842a6efe9f 100644
--- a/src/gravity/Default/gravity.h
+++ b/src/gravity/Default/gravity.h
@@ -42,6 +42,9 @@ gravity_compute_timestep_external(const struct external_potential* potential,
   dt =
       fminf(dt, external_gravity_pointmass_timestep(potential, phys_const, gp));
 #endif
+#ifdef EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
+  dt = fminf(dt, external_gravity_isothermalpotential_timestep(potential, phys_const, gp));
+#endif
 
   return dt;
 }
@@ -117,6 +120,9 @@ __attribute__((always_inline)) INLINE static void external_gravity(
 #ifdef EXTERNAL_POTENTIAL_POINTMASS
   external_gravity_pointmass(potential, phys_const, gp);
 #endif
+#ifdef EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
+  external_gravity_isothermalpotential(potential, phys_const, gp);
+#endif
 }
 
 /**
diff --git a/src/potentials.c b/src/potentials.c
index 98e57d7959963e07cfbbd2fdb60a0df504e6a487..d55d3d669f1a146a0932c46b551ee06f37ed3921 100644
--- a/src/potentials.c
+++ b/src/potentials.c
@@ -48,6 +48,16 @@ void potential_init(const struct swift_params* parameter_file,
       parser_get_param_double(parameter_file, "PointMass:mass");
 
 #endif /* EXTERNAL_POTENTIAL_POINTMASS */
+#ifdef EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
+  potential -> isothermal_potential.x = 
+	 parser_get_param_double(parameter_file, "IsothermalPotential:position_x");
+  potential -> isothermal_potential.y = 
+	 parser_get_param_double(parameter_file, "IsothermalPotential:position_y");
+  potential -> isothermal_potential.z = 
+	 parser_get_param_double(parameter_file, "IsothermalPotential:position_z");
+  potential -> isothermal_potential.vrot = 
+	 parser_get_param_double(parameter_file, "IsothermalPotential:vrot");
+#endif /* EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL */
 }
 
 /**
@@ -62,4 +72,9 @@ void potential_print(const struct external_potential* potential) {
           potential->point_mass.x, potential->point_mass.y,
           potential->point_mass.z, potential->point_mass.mass);
 #endif /* EXTERNAL_POTENTIAL_POINTMASS */
+#ifdef EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
+  message("Isothermal potential properties are (x,y,z) = (%e, %e, %e), vrot = %e",
+			 potential->isothermal_potential.x, potential->isothermal_potential.y,
+  			 potential->isothermal_potential.z, potential->isothermal_potential.vrot);
+#endif /* EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL */
 }
diff --git a/src/potentials.h b/src/potentials.h
index c3db5a3d2231c93b1d83aa94bca83f7f7d7106bc..c2ee511af3e390a4942c176867f64b8c7bd43fa5 100644
--- a/src/potentials.h
+++ b/src/potentials.h
@@ -44,7 +44,68 @@ struct external_potential {
     double mass;
   } point_mass;
 #endif
+#ifdef EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
+  struct {
+	 double x, y, z;
+	 double vrot;
+  } isothermal_potential;
+#endif
 };
+/* Include external isothermal potential */
+#ifdef EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL
+
+#define EXTERNAL_GRAVITY_TIMESTEP_PREFACTOR  0.03f
+/**
+ * @brief Computes the time-step due to the acceleration from a point mass
+ *
+ * @param phys_cont The physical constants in internal units.
+ * @param gp Pointer to the g-particle data.
+ */
+__attribute__((always_inline))
+    INLINE static float external_gravity_isothermalpotential_timestep(
+		  const struct external_potential* potential,
+        const struct phys_const* const phys_const,
+        const struct gpart* const g) {
+
+  const float dx    = g->x[0] - potential->isothermal_potential.x;
+  const float dy    = g->x[1] - potential->isothermal_potential.y;
+  const float dz    = g->x[2] - potential->isothermal_potential.z;
+  const float rinv2 = 1.f / (dx * dx + dy * dy + dz * dz);
+  const float drdv  = dx * (g->v_full[0]) + dy * (g->v_full[1]) + dz * (g->v_full[2]);
+  const double vrot = potential->isothermal_potential.vrot;
+
+  const float dota_x = vrot * vrot * rinv2 * (g->v_full[0] - 2 * drdv * dx * rinv2);
+  const float dota_y = vrot * vrot * rinv2 * (g->v_full[1] - 2 * drdv * dy * rinv2);
+  const float dota_z = vrot * vrot * rinv2 * (g->v_full[2] - 2 * drdv * dz * rinv2);
+  const float dota_2 = dota_x * dota_x + dota_y * dota_y + dota_z * dota_z;
+  const float a_2 = g->a_grav[0] * g->a_grav[0] + g->a_grav[1] * g->a_grav[1] +
+                    g->a_grav[2] * g->a_grav[2];
+
+  //  error(" dx= %e dvx= %e rinv2= %e a2= %e dota_2= %e dt= %e", dx, g->v_full[1], rinv2, a_2, dota_2, 0.03f * sqrtf(a_2 / dota_2));
+
+  return EXTERNAL_GRAVITY_TIMESTEP_PREFACTOR * sqrtf(a_2 / dota_2);
+}
+/**
+ * @brief Computes the gravitational acceleration of a particle due to a point
+ * mass
+ *
+ * @param phys_cont The physical constants in internal units.
+ * @param gp Pointer to the g-particle data.
+ */
+__attribute__((always_inline)) INLINE static void external_gravity_isothermalpotential(const struct external_potential* potential, const struct phys_const* const phys_const, struct gpart* g) {
+
+  const float dx    = g->x[0] - potential->isothermal_potential.x;
+  const float dy    = g->x[1] - potential->isothermal_potential.y;
+  const float dz    = g->x[2] - potential->isothermal_potential.z;
+  const float rinv2 = 1.f / (dx * dx + dy * dy + dz * dz);
+
+  const double vrot = potential->isothermal_potential.vrot;
+  g->a_grav[0] += -vrot * vrot * rinv2 * dx;
+  g->a_grav[1] += -vrot * vrot * rinv2 * dy;
+  g->a_grav[2] += -vrot * vrot * rinv2 * dz;
+  // error(" %f %f %f %f", vrot, rinv2, dx, g->a_grav[0]);
+}
+#endif /* EXTERNAL_POTENTIAL_ISOTHERMALPOTENTIAL */
 
 /* Include exteral pointmass potential */
 #ifdef EXTERNAL_POTENTIAL_POINTMASS