Home > fvcom_prepro > calc_sponge_radius.m

calc_sponge_radius

PURPOSE ^

Calculate a variable sponge radius based on distance to the boundary

SYNOPSIS ^

function [spongeRadius] = calc_sponge_radius(Mobj,Nlist)

DESCRIPTION ^

 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.

==========================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

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

Generated on Wed 20-Feb-2019 16:06:01 by m2html © 2005