


Calculate a variable sponge radius based on distance to the boundary
node's furthest neighbour.
(Adapted from Phil Hall's 'produce_netcdf_input_data.py')
spongeRadius = calc_sponge_radius(Mobj,Nlist)
DESCRIPTION
Calculates the sponge radius for each node on the open boundary, based
on the minimum of either the distance to the node's furthest
neighbour, or 100 km.
INPUT
Mobj = Matlab mesh object
Nlist = List of nodes
OUTPUT
spongeRadius = List of variable sponge radii
EXAMPLE USAGE
spongeRadius = calc_sponge_radius(Mobj,Nlist)
Author(s)
Karen Amoudry (National Oceanography Centre, Liverpool)
Pierre Cazenave (Plymouth Marine Laboratory)
Revision history:
2013-01-02 KJA bug fix: amended usage of 'unique' to prevent it from
sorting the values it returns. Amended by Pierre to support pre-2012
versions of MATLAB whilst giving the same result.
2013-07-16 KJA: adapted function to remove dependency on the Matlab
Mapping Toolbox.
==========================================================================

0001 function [spongeRadius] = calc_sponge_radius(Mobj,Nlist) 0002 0003 % Calculate a variable sponge radius based on distance to the boundary 0004 % node's furthest neighbour. 0005 % (Adapted from Phil Hall's 'produce_netcdf_input_data.py') 0006 % 0007 % spongeRadius = calc_sponge_radius(Mobj,Nlist) 0008 % 0009 % DESCRIPTION 0010 % Calculates the sponge radius for each node on the open boundary, based 0011 % on the minimum of either the distance to the node's furthest 0012 % neighbour, or 100 km. 0013 % 0014 % INPUT 0015 % Mobj = Matlab mesh object 0016 % Nlist = List of nodes 0017 % 0018 % OUTPUT 0019 % spongeRadius = List of variable sponge radii 0020 % 0021 % EXAMPLE USAGE 0022 % spongeRadius = calc_sponge_radius(Mobj,Nlist) 0023 % 0024 % Author(s) 0025 % Karen Amoudry (National Oceanography Centre, Liverpool) 0026 % Pierre Cazenave (Plymouth Marine Laboratory) 0027 % 0028 % Revision history: 0029 % 2013-01-02 KJA bug fix: amended usage of 'unique' to prevent it from 0030 % sorting the values it returns. Amended by Pierre to support pre-2012 0031 % versions of MATLAB whilst giving the same result. 0032 % 2013-07-16 KJA: adapted function to remove dependency on the Matlab 0033 % Mapping Toolbox. 0034 % 0035 %========================================================================== 0036 subname = 'calc_sponge_radius'; 0037 global ftbverbose 0038 if(ftbverbose) 0039 fprintf('\n') 0040 fprintf(['begin : ' subname '\n']) 0041 end 0042 0043 %-------------------------------------------------------------------------- 0044 % Get a unique list and make sure they are in the range of node numbers 0045 %-------------------------------------------------------------------------- 0046 % Make this work in versions of MATLAB older than 2012a (newer versions 0047 % can just use unique(A, 'stable'), but checking versions is a pain). 0048 [~, Nidx] = unique(Nlist); 0049 Nlist = Nlist(sort(Nidx)); 0050 0051 spongeRadius = 100000+zeros(size(Nlist)); 0052 0053 % For each node on the open boundary 0054 for i =1:length(Nlist) 0055 % Find the neighbouring nodes 0056 [r,c]=find(Mobj.tri==Nlist(i)); 0057 neighbours = Mobj.tri(r,:); 0058 [~,neighidx] = unique(Mobj.tri(r,:)); 0059 neighbours = neighbours(sort(neighidx)); 0060 0061 % Remove the node of interest from the neighbours list 0062 n = find(neighbours~=Nlist(i)); 0063 neighbours = neighbours(n); 0064 0065 % Calculate the arc length (in degrees) between the node and its 0066 % neighbours 0067 % arclen = distance(Mobj.lat(Nlist(i)),Mobj.lon(Nlist(i)),... 0068 % Mobj.lat(neighbours),Mobj.lon(neighbours)); 0069 % % Convert from degrees to whole metres 0070 % arclen = ceil(1000*deg2km(arclen)); 0071 0072 0073 % Adapted to avoid using Mapping toolbox 0074 % Step 1: convert lat/lon to radians 0075 lat1 = Mobj.lat(Nlist(i)) .* pi./180; 0076 lon1 = Mobj.lon(Nlist(i)) .* pi./180; 0077 lat2 = Mobj.lat(neighbours) .* pi./180; 0078 lon2 = Mobj.lon(neighbours) .* pi./180; 0079 % Step 2: calculate distance in radians 0080 a = sin((lat2-lat1)/2).^2 + cos(lat1) .* cos(lat2) .*... 0081 sin((lon2-lon1)/2).^2; 0082 arclen = 2 * atan2(sqrt(a),sqrt(1 - a)); 0083 0084 % Calculate distance in whole metres 0085 arclen = ceil(1000 .* 6371 .* arclen); 0086 0087 % If the smallest distance is less than 100km, keep it 0088 if min(arclen)<spongeRadius(i) 0089 spongeRadius(i)=min(arclen); 0090 end 0091 end 0092 0093 if(ftbverbose) 0094 fprintf(['end : ' subname '\n']) 0095 end 0096