Merge lp:~fluidity-core/fluidity/fluidity-initialisation-from_netcdf into lp:fluidity

Proposed by Stephan Kramer
Status: Work in progress
Proposed branch: lp:~fluidity-core/fluidity/fluidity-initialisation-from_netcdf
Merge into: lp:fluidity
Diff against target: 2679 lines (+1141/-1170)
23 files modified
femtools/Makefile.dependencies (+1/-1)
femtools/SampleNetCDF_fortran.F90 (+35/-3)
ocean_forcing/SampleNetCDF.cpp (+44/-1)
ocean_forcing/SampleNetCDF.h (+7/-1)
preprocessor/Boundary_Conditions_From_Options.F90 (+93/-61)
preprocessor/Initialise_Fields.F90 (+31/-7)
preprocessor/Makefile.dependencies (+2/-1)
schemas/input_output.rnc (+10/-3)
schemas/input_output.rng (+11/-3)
schemas/prognostic_field_options.rnc (+2/-194)
schemas/prognostic_field_options.rng (+2/-272)
schemas/shallow_water_options.rnc (+0/-12)
schemas/shallow_water_options.rng (+15/-31)
schemas/test_advection_diffusion_options.rnc (+0/-241)
schemas/test_advection_diffusion_options.rng (+15/-339)
tests/sample_netcdf_test/Makefile (+9/-0)
tests/sample_netcdf_test/create_netcdf_test.py (+70/-0)
tests/sample_netcdf_test/sample.flml (+658/-0)
tests/sample_netcdf_test/sample_netcdf_test.xml (+24/-0)
tests/sample_netcdf_test/src/box_on_sphere.geo (+17/-0)
tests/sample_netcdf_test/src/definitions.geo (+41/-0)
tests/sample_netcdf_test/src/shorelines.geo (+8/-0)
tests/sample_netcdf_test/src/shorelines_with_boundaries.geo (+46/-0)
To merge this branch: bzr merge lp:~fluidity-core/fluidity/fluidity-initialisation-from_netcdf
Reviewer Review Type Date Requested Status
Stephan Kramer Pending
Review via email: mp+95576@code.launchpad.net

Description of the change

This merge achieves 3 things:
1) Change tidal forcing boundary condition so that the phase is no longer interpolated (this causes issues at the 360-0 line). Instead the tidal elevation is calculated as:
  A(x) cos(omega*t+alpha(x)) = A(x) cos(omega*t) cos(alpha(x)-sin(omega*t) sin(alpha(x))
                             = Re[ A(x) exp(i omega*t) exp(i alpha(x)) ]
where A(x), alpha(x) and omega are the amplitude, phase and frequency of the tidal constituent. We therefore now compute A(x)*cos(alpha(x)) and A(x)*sin(alpha(x)), the real and imaginary components of the complex tidal constituent, at the nodes of the netCDF first, before interpolating to the fluidity mesh.
2) The netCDF file is only read once at the beginning of the run instead of every timestep.
3) Prescribed fields have an option to be prescribed from a netCDF file using the same netCDF reader as used for the tidal boundary forcing, so we can actually see what data is being used. This is done by adding a new "netcdf" format (next to the existing "vtu" format under "from_file"), under which the user can specify which netCDF variable to read.

The reason these 3 things are combined in this merge is to allow testing of the tidal boundary forcing - currently no such tests exist. This merge introduces the sample_netcdf_test/ that tests
both the SampleNetCDF reader and the actual tidal boundary condition values. This is done by creating a netCDF file using Scientific python with variables set via an analytical function and checking the same values are read in fluidity.

Smaller changes:
- taking away the dirichlet/from_file/tidal option under various balance pressure fields. For these cases (other than field%name=="Pressure") the tidal forcing was never multiplied by g, so this would not have worked.
- because this was also still present under the no longer existing "prognostic free surface", this has now finally been taken out of the schema - which meant also deleting it from the shallow water and test_advection_diffussion schemes.
- fix intents of id argument of most SampleNetCDF_XXX() routines.
- add SampleNetCDF_to_field() routine that interpolate netCDF data to scalar_field on the fluidity mesh

To post a comment you must log in.
3943. By Stephan Kramer

Fix initialising prescribed fields from "netcdf" format in parallel.

Revision history for this message
Stephan Kramer (s-kramer) wrote :

I use python code for all of this now, that I'll make available soon. Therefore retracting my merge request for now.

Revision history for this message
Adam Candy (asc) wrote :

> I use python code for all of this now, that I'll make available soon.
> Therefore retracting my merge request for now.

How very gentlemanly of you!

I have a branch implementing some of the above, so we could take a look at the two and merge in a combination. The NetCDF input certainly requires an improvement - Jon's also mentioned working on this?

I think my branch with additional debugging for the NetCDf readers (a portion of them) is already in. This does give information on the location of problem reads, warns when values are recast and is accompanied by a suite of tests.

Revision history for this message
Jon Hill (jon-hill) wrote :

I have a half-competed branch for reading netcdf files and putting those
data onto a mesh. I was stuck with a unit test not compiling if I
remember correctly.

The branch is at:
bzr+ssh://bazaar.launchpad.net/~fluidity-core/fluidity/refactor-netcdf/

I was trying to create a generic reader which created a mesh using
Delauny triangulation. We can then use Fluidity's mesh interpolation to
put this on any mesh.

Michael Lange is also interested in this, including outputting stat
files and detectors to NetCDF.

Jon

On 09/05/13 12:14, Adam Candy wrote:
>> I use python code for all of this now, that I'll make available soon.
>> Therefore retracting my merge request for now.
>
> How very gentlemanly of you!
>
> I have a branch implementing some of the above, so we could take a look at the two and merge in a combination. The NetCDF input certainly requires an improvement - Jon's also mentioned working on this?
>
> I think my branch with additional debugging for the NetCDf readers (a portion of them) is already in. This does give information on the location of problem reads, warns when values are recast and is accompanied by a suite of tests.
>

--
Dr Jon Hill
Research Fellow
AMCG, Imperial College London
Mob: 07748254812

Unmerged revisions

3943. By Stephan Kramer

Fix initialising prescribed fields from "netcdf" format in parallel.

3942. By Stephan Kramer

Merging from trunk.

3941. By Stephan Kramer

Cleaning up before merge request.

3940. By Stephan Kramer

Should have committed these file for the test as well.

3939. By Stephan Kramer

Merging in from trunk.

3938. By Stephan Kramer

Actually testing the values brought up two more bugs. Now pretty confident it actually works.

3937. By Stephan Kramer

Add prescribed field initialised from netcdf, to be compared with a python diagnostic field using the same function used to create the netcdf file.
Fixed mem leak in initialsing form netcdf.

3936. By Stephan Kramer

Several bug fixes. Test now runs through and seems to give sensible answers.

3935. By Stephan Kramer

Start of a new test to test SampleNetCDF and tidal boundary conditions.
Does not yet work.
Accidentily removed tidal boundary conditions also from "Pressure" - putting back in.

3934. By Stephan Kramer

This commit address 2 issues:
* interpolating errors along the phase=360 lines of tidal forcing read netcdf files
* the tidal forcing is no longer read every timestep, but only once in populate_state - this prevents reading the entire netcdf tidal atlas on every processor every timestep.

In femtools/SampleNetCDF_fortran.F90:
- fix intents of id argument of most SampleNetCDF_XXX() routines.
- add SampleNetCDF_to_field that sets a scalar field from netcdf values.
In preprocessor/Boundary_Conditions_From_Options.F90
- add new populate_tidal_bc() routine, that initialises the tidal bc calculation by computing the real and complex components of A(x)exp(i*alpha(x)), where A(x) is amplitude and alpha(x) the phase, and store these components as surface fields under the bc.
- in set_tidal_bc_value() it now uses these to compute the free surface contributions of the different tidal components.
In schemas/:
- taking away the dirichlet/from_file/tidal option under various balance pressure fields. For these cases (other than field%name=="Pressure") the tidal forcing was never multiplied by g, so this would not have worked.
- because this was also still present under the no longer existing "prognostic free surface", this has now finally been taken out of the schema - which meant also deleting it from the shallow water and test_advection_diffussion schemes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'femtools/Makefile.dependencies'
2--- femtools/Makefile.dependencies 2012-01-20 15:54:44 +0000
3+++ femtools/Makefile.dependencies 2012-03-27 11:21:19 +0000
4@@ -933,7 +933,7 @@
5 @true
6
7 SampleNetCDF_fortran.o ../include/samplenetcdf.mod: SampleNetCDF_fortran.F90 \
8- ../include/fldebug.mod
9+ ../include/coordinates.mod ../include/fields.mod ../include/fldebug.mod
10
11 ../include/shape_functions.mod: Shape_Functions.o
12 @true
13
14=== modified file 'femtools/SampleNetCDF_fortran.F90'
15--- femtools/SampleNetCDF_fortran.F90 2010-11-09 14:08:19 +0000
16+++ femtools/SampleNetCDF_fortran.F90 2012-03-27 11:21:19 +0000
17@@ -27,6 +27,8 @@
18
19 module SampleNetCDF
20 use FLDebug
21+ use fields
22+ use coordinates
23 implicit none
24 contains
25
26@@ -39,13 +41,25 @@
27
28 subroutine SampleNetCDF_SetVariable(id, varname)
29 character(len=*), intent(in)::varname
30- integer, intent(out)::id
31+ integer, intent(in)::id
32
33 call samplenetcdf_setvariable_c(id, varname, len_trim(varname))
34 end subroutine SampleNetCDF_SetVariable
35
36+ subroutine SampleNetCDF_ApplyCos(id)
37+ integer, intent(in)::id
38+
39+ call samplenetcdf_applycos_c(id)
40+ end subroutine SampleNetCDF_ApplyCos
41+
42+ subroutine SampleNetCDF_ApplySin(id)
43+ integer, intent(in)::id
44+
45+ call samplenetcdf_applysin_c(id)
46+ end subroutine SampleNetCDF_ApplySin
47+
48 subroutine SampleNetCDF_GetValue(id, longitude, latitude, val)
49- integer, intent(out)::id
50+ integer, intent(in)::id
51 real, intent(out)::longitude, latitude
52 real, intent(out)::val
53
54@@ -53,9 +67,27 @@
55 end subroutine SampleNetCDF_GetValue
56
57 subroutine SampleNetCDF_Close(id)
58- integer, intent(out)::id
59+ integer, intent(in)::id
60
61 call samplenetcdf_close_c(id)
62 end subroutine SampleNetCDF_Close
63+
64+ subroutine SampleNetCDF_to_field(id, field, bc_position)
65+ ! set scalar field from netcdf values
66+ integer, intent(in):: id
67+ type(scalar_field), intent(inout):: field
68+ type(vector_field), intent(in):: bc_position
69+
70+ integer:: i
71+ real:: longitude, latitude, xyz(3), value
72+
73+ do i=1, node_count(bc_position)
74+ xyz = node_val(bc_position, i)
75+ call LongitudeLatitude(xyz, longitude, latitude)
76+ call SampleNetCDF_GetValue(id, longitude, latitude, value)
77+ call set(field, i, value)
78+ end do
79+
80+ end subroutine SampleNetCDF_to_field
81
82 end module SampleNetCDF
83
84=== modified file 'ocean_forcing/SampleNetCDF.cpp'
85--- ocean_forcing/SampleNetCDF.cpp 2012-02-20 17:52:19 +0000
86+++ ocean_forcing/SampleNetCDF.cpp 2012-03-27 11:21:19 +0000
87@@ -25,6 +25,7 @@
88 #include <iostream>
89 #include <map>
90 #include <vector>
91+#include <algorithm>
92
93 #include <vtk.h>
94
95@@ -65,6 +66,7 @@
96 }
97
98 data = in.data;
99+ read_data = in.read_data;
100 verbose = in.verbose;
101
102 reader = in.reader;
103@@ -189,7 +191,19 @@
104 if(verbose)
105 cout<<"void SampleNetCDF::SetVariable("<<varname<<")\n";
106
107- reader.Read(varname, data);
108+ reader.Read(varname, read_data);
109+ data = read_data.begin();
110+}
111+
112+void SampleNetCDF::ApplyFunction(double f(double x)){
113+ // apply transformation to read data
114+ // transformed data is stored in manipulated_data, allocate it to right size (or reuse)
115+ if (manipulated_data.size()!=read_data.size())
116+ manipulated_data.resize(read_data.size());
117+ // iterate over read_data, apply function f and store in manipulated_data
118+ transform(read_data.begin(), read_data.end(), manipulated_data.begin(), f);
119+ // from now on we sample the manipulated data:
120+ data = manipulated_data.begin();
121 }
122
123 void SampleNetCDF::VerboseOff(){
124@@ -226,6 +240,35 @@
125
126 netcdf_sampler[*id].SetVariable(string(varname, *len));
127 }
128+
129+ // auxilary functions cosdeg and sindeg: cos and sin as function of degrees rather than radials
130+ double const pi=4*atan(1);
131+ double cosdeg(double deg){
132+ return cos(pi*deg/180);
133+ }
134+ double sindeg(double deg){
135+ return sin(pi*deg/180);
136+ }
137+
138+#define samplenetcdf_applycos_fc F77_FUNC_(samplenetcdf_applycos_c, SAMPLENETCDF_APPLYCOS_C)
139+ void samplenetcdf_applycos_fc(const int *id){
140+ if(netcdf_sampler.find(*id)==netcdf_sampler.end()){
141+ cerr<<"ERROR: netcdf file has not been opened\n";
142+ exit(-1);
143+ }
144+
145+ netcdf_sampler[*id].ApplyFunction(cosdeg);
146+ }
147+
148+#define samplenetcdf_applysin_fc F77_FUNC_(samplenetcdf_applysin_c, SAMPLENETCDF_APPLYSIN_C)
149+ void samplenetcdf_applysin_fc(const int *id){
150+ if(netcdf_sampler.find(*id)==netcdf_sampler.end()){
151+ cerr<<"ERROR: netcdf file has not been opened\n";
152+ exit(-1);
153+ }
154+
155+ netcdf_sampler[*id].ApplyFunction(sindeg);
156+ }
157
158 #define samplenetcdf_getvalue_fc F77_FUNC_(samplenetcdf_getvalue_c, SAMPLENETCDF_GETVALUE_C)
159 void samplenetcdf_getvalue_fc(const int *id, const double *longitude, const double *latitude, double *val){
160
161=== modified file 'ocean_forcing/SampleNetCDF.h'
162--- ocean_forcing/SampleNetCDF.h 2009-12-16 14:11:47 +0000
163+++ ocean_forcing/SampleNetCDF.h 2012-03-27 11:21:19 +0000
164@@ -52,6 +52,7 @@
165
166 void SetFile(std::string);
167 void SetVariable(std::string);
168+ void ApplyFunction(double f(double x));
169
170 void VerboseOff();
171 void VerboseOn();
172@@ -66,7 +67,12 @@
173 double spacing[2]; // Grid spacing
174 int dimension[2]; // Grid dimensions
175
176- std::vector<double> data;
177+ // random access iterator over the data being sampled
178+ // (this may be iterating manipulated_data or read_data):
179+ std::vector<double>::iterator data;
180+
181+ std::vector<double> read_data; // original data in netcdf file
182+ std::vector<double> manipulated_data; // data after manipulation
183 bool verbose;
184
185 NetCDFReader reader;
186
187=== modified file 'preprocessor/Boundary_Conditions_From_Options.F90'
188--- preprocessor/Boundary_Conditions_From_Options.F90 2011-11-23 13:46:31 +0000
189+++ preprocessor/Boundary_Conditions_From_Options.F90 2012-03-27 11:21:19 +0000
190@@ -260,6 +260,10 @@
191 call insert_surface_field(field, i+1, surface_field)
192 call deallocate(surface_field)
193
194+ if (have_option(trim(bc_path_i)//"/type::dirichlet/from_file")) then
195+ call populate_tidal_bc(field, i+1, bc_position, trim(bc_path_i)//"/type::dirichlet/from_file")
196+ end if
197+
198 case("robin")
199
200 call allocate(surface_field, surface_mesh, name="order_zero_coefficient")
201@@ -767,7 +771,7 @@
202 ! Tidal: set free surface height at the boundary.
203 if (have_option(trim(bc_type_path)//"/from_file")) then
204 ! Special case for tidal harmonic boundary conditions
205- call set_tidal_bc_value(surface_field, bc_position, trim(bc_type_path), field%name)
206+ call set_tidal_bc_value(field, surface_field, i+1, trim(bc_type_path)//"/from_file")
207 else if (have_option(trim(bc_type_path)//"/NEMO_data")) then
208 call set_nemo_bc_value(state, surface_field, bc_position, trim(bc_type_path), field%name, surface_element_list)
209 else
210@@ -1092,71 +1096,99 @@
211
212 end subroutine set_vector_boundary_conditions_values
213
214- subroutine set_tidal_bc_value(surface_field, bc_position, bc_type_path, field_name)
215+ subroutine populate_tidal_bc(field, bc_index, bc_position, bc_option_path)
216 ! tidal_forcing - asc
217- type(scalar_field), intent(inout):: surface_field
218- type(vector_field), intent(in):: bc_position
219- character(len=*), intent(in):: bc_type_path, field_name
220+ type(scalar_field), intent(inout):: field
221+ integer, intent(in):: bc_index
222+ type(vector_field), intent(inout):: bc_position
223+ ! option path pointing to tidal constituents
224+ character(len=*), intent(in):: bc_option_path
225
226- real :: current_time, frequency, amplitude_factor
227+ type(scalar_field):: amplitude, real_component, imag_component
228 integer :: constituent_count, i, j, id, stat
229 character(len=3) :: constituent_name
230 character(len=4096) :: file_name, variable_name_amplitude, variable_name_phase
231- real, dimension(:), allocatable::amplitude, phase
232- real :: xyz(3), longitude, latitude
233- real :: gravty
234-
235- allocate(amplitude(node_count(surface_field)), phase(node_count(surface_field)))
236-
237- if(have_option(trim(bc_type_path)//"/from_file/tidal")) then
238- call set(surface_field, 0.0)
239- call get_option("/timestepping/current_time", current_time)
240- constituent_count = option_count(trim(bc_type_path)//"/from_file/tidal")
241-
242- do i=0, constituent_count-1
243- amplitude = 0.0
244- phase = 0.0
245- call get_option(trim(bc_type_path)//"/from_file/tidal["//int2str(i)//"/amplitude_factor", amplitude_factor, stat=stat)
246- if (stat/=0) then
247- amplitude_factor = 1.0
248- end if
249-
250- ! Taken from E.W. Schwiderski - Rev. Geophys. Space Phys. Vol. 18 No. 1 pp. 243--268, 1980
251- call get_option(trim(bc_type_path)//"/from_file/tidal["//int2str(i)//"]/name", constituent_name, stat=stat)
252-
253- frequency = get_tidal_frequency(constituent_name)
254-
255- call get_option(trim(bc_type_path)//"/from_file/tidal["//int2str(i)//"]/file_name", file_name, stat=stat)
256- call get_option(trim(bc_type_path)//"/from_file/tidal["//int2str(i)//"]/variable_name_amplitude", variable_name_amplitude, stat=stat)
257- call get_option(trim(bc_type_path)//"/from_file/tidal["//int2str(i)//"]/variable_name_phase", variable_name_phase, stat=stat)
258-
259- call SampleNetCDF_Open(trim(file_name), id)
260- call SampleNetCDF_SetVariable(id, trim(variable_name_amplitude))
261- do j=1, node_count(bc_position)
262- xyz = node_val(bc_position, j)
263- call LongitudeLatitude(xyz, longitude, latitude)
264- call SampleNetCDF_GetValue(id, longitude, latitude, amplitude(j))
265- end do
266- call SampleNetCDF_SetVariable(id, trim(variable_name_phase))
267- do j=1, node_count(bc_position)
268- xyz = node_val(bc_position, j)
269- call LongitudeLatitude(xyz, longitude, latitude)
270- call SampleNetCDF_GetValue(id, longitude, latitude, phase(j))
271- end do
272-
273- call get_option('/physical_parameters/gravity/magnitude', gravty)
274- do j=1, node_count(bc_position)
275- if (field_name=="Pressure") then
276- call addto(surface_field, j, &
277- gravty * amplitude(j) * cos( frequency * current_time - ( phase(j) * pi / 180 ) ))
278- else
279- call addto(surface_field, j, &
280- amplitude(j) * cos( frequency * current_time - ( phase(j) * pi / 180 ) ))
281- end if
282- end do
283- call SampleNetCDF_Close(id)
284- end do
285- end if
286+
287+ constituent_count = option_count(trim(bc_option_path)//"/tidal")
288+
289+ do i=0, constituent_count-1
290+
291+ ! Taken from E.W. Schwiderski - Rev. Geophys. Space Phys. Vol. 18 No. 1 pp. 243--268, 1980
292+ call get_option(trim(bc_option_path)//"/tidal["//int2str(i)//"]/name", constituent_name)
293+
294+ call get_option(trim(bc_option_path)//"/tidal["//int2str(i)//"]/file_name", file_name)
295+ call get_option(trim(bc_option_path)//"/tidal["//int2str(i)//"]/variable_name_amplitude", variable_name_amplitude)
296+ call get_option(trim(bc_option_path)//"/tidal["//int2str(i)//"]/variable_name_phase", variable_name_phase)
297+
298+ call SampleNetCDF_Open(trim(file_name), id)
299+
300+ ! sample the tidal amplitude at the boundary nodes
301+ call SampleNetCDF_SetVariable(id, trim(variable_name_amplitude))
302+ call allocate(amplitude, bc_position%mesh, "amplitude")
303+ call SampleNetCDF_to_field(id, amplitude, bc_position)
304+
305+ ! we compute the real and imaginary component of the tide:
306+ ! A(x) * exp(i*alpha(x)) = A(x)cos(alpha(x)) + i * A(x)sin(alpha(x))
307+ ! where A(x) is the amplitude, and alpha(x) the phase
308+
309+ ! sample cos(alpha(x)) and multiply with A(x) at the nodes
310+ call SampleNetCDF_SetVariable(id, trim(variable_name_phase))
311+ call SampleNetCDF_ApplyCos(id)
312+ call allocate(real_component, bc_position%mesh, trim(constituent_name)//"real")
313+ call SampleNetCDF_to_field(id, real_component, bc_position)
314+ call scale(real_component, amplitude)
315+ call insert_surface_field(field, bc_index, real_component)
316+ call deallocate(real_component)
317+
318+ ! sample sin(alpha(x)) and multiply with A(x) at the nodes
319+ call SampleNetCDF_ApplySin(id)
320+ call allocate(imag_component, bc_position%mesh, trim(constituent_name)//"imag")
321+ call SampleNetCDF_to_field(id, imag_component, bc_position)
322+ call scale(imag_component, amplitude)
323+ call insert_surface_field(field, bc_index, imag_component)
324+ call deallocate(imag_component)
325+
326+ call deallocate(amplitude)
327+ call SampleNetCDF_Close(id)
328+ end do
329+
330+ end subroutine populate_tidal_bc
331+
332+ subroutine set_tidal_bc_value(field, surface_field, bc_index, bc_option_path)
333+ ! tidal components are added into the dirichlet "value" surface_field
334+ type(scalar_field), intent(inout):: field, surface_field
335+ integer, intent(in):: bc_index
336+ ! option path pointing to tidal constituents
337+ character(len=*), intent(in):: bc_option_path
338+
339+ type(scalar_field), pointer:: real_component, imag_component
340+ integer :: constituent_count, i
341+ character(len=3) :: constituent_name
342+ real :: g, t, omega
343+
344+ call get_option("/timestepping/current_time", t)
345+ call get_option('/physical_parameters/gravity/magnitude', g)
346+
347+ call zero(surface_field)
348+
349+ constituent_count = option_count(trim(bc_option_path)//"/tidal")
350+
351+ do i=0, constituent_count-1
352+ ! Taken from E.W. Schwiderski - Rev. Geophys. Space Phys. Vol. 18 No. 1 pp. 243--268, 1980
353+ call get_option(trim(bc_option_path)//"/tidal["//int2str(i)//"]/name", constituent_name)
354+ omega = get_tidal_frequency(constituent_name)
355+
356+ ! the free surface contribution is calculated as:
357+ ! g*A(x) cos(omega * t + alpha(x)) = g*A(x) cos(alpha(x) cos(omega *t) - g*A(x) sin(alpha(x) sin(omega *t)
358+
359+ real_component => extract_surface_field(field, bc_index, trim(constituent_name)//"real")
360+ call addto(surface_field, real_component, scale=g*cos(omega*t))
361+
362+ imag_component => extract_surface_field(field, bc_index, trim(constituent_name)//"imag")
363+ call addto(surface_field, imag_component, scale=-g*sin(omega*t))
364+
365+ end do
366+
367 end subroutine set_tidal_bc_value
368
369 subroutine set_nemo_bc_value(state, surface_field, bc_position, bc_type_path, field_name, surface_element_list)
370
371=== modified file 'preprocessor/Initialise_Fields.F90'
372--- preprocessor/Initialise_Fields.F90 2012-02-09 22:34:28 +0000
373+++ preprocessor/Initialise_Fields.F90 2012-03-27 11:21:19 +0000
374@@ -38,6 +38,8 @@
375 use nemo_states_module
376 use physics_from_options
377 use load_netcdf_module
378+use tidal_module
379+use SampleNetCDF
380
381 implicit none
382
383@@ -84,9 +86,11 @@
384 character(len=PYTHON_FUNC_LEN) :: func
385 real :: current_time
386 real :: gravity_magnitude
387-
388- real value
389- integer nid
390+
391+ ! some variables for reading from netcdf and climatology
392+ real, dimension(3):: xyz
393+ real:: value, longitude, latitude
394+ integer:: id, nid
395
396 ! Find out whether initial condition is constant or generated by a
397 ! python function (or comes from something else).
398@@ -123,13 +127,15 @@
399
400 call get_option(trim(path) // "/from_file/format/name", format)
401 call get_option(trim(path) // "/from_file/file_name", filename)
402- if(isparallel()) then
403- filename = parallel_filename(trim_file_extension(filename), ".vtu")
404- end if
405- ewrite(2, *) "Initialising field " // trim(field%name) // " from file " // trim(filename)
406
407 select case (format)
408 case ("vtu")
409+
410+ if(isparallel()) then
411+ filename = parallel_filename(trim_file_extension(filename), ".vtu")
412+ end if
413+ ewrite(2, *) "Initialising field " // trim(field%name) // " from file " // trim(filename)
414+
415 call get_option(trim(path) // "/from_file/format::vtu/field_name", field_name, default = field%name)
416 read_field => vtk_cache_read_scalar_field(filename, field_name)
417
418@@ -164,7 +170,25 @@
419
420 call set(field, read_field)
421
422+ case ("netcdf")
423+
424+ ewrite(2, *) "Initialising field " // trim(field%name) // " from file " // trim(filename)
425
426+ call get_option(trim(path) // "/from_file/format::netcdf/field_name", field_name)
427+ if (field%mesh==position%mesh) then
428+ field_position=position
429+ call incref(field_position)
430+ else
431+ ! otherwise the position mapped onto field%mesh
432+ field_position = get_remapped_coordinates(position, field%mesh)
433+ end if
434+
435+ call SampleNetCDF_Open(trim(filename), id)
436+ call SampleNetCDF_SetVariable(id, trim(field_name))
437+ call SampleNetCDF_to_field(id, field, field_position)
438+ call SampleNetCDF_Close(id)
439+ call deallocate(field_position)
440+
441 case ("climatology (Boyer2005)")
442
443 do nid=1, node_count(position)
444
445=== modified file 'preprocessor/Makefile.dependencies'
446--- preprocessor/Makefile.dependencies 2011-10-26 19:57:55 +0000
447+++ preprocessor/Makefile.dependencies 2012-03-27 11:21:19 +0000
448@@ -36,7 +36,8 @@
449 ../include/fdebug.h ../include/fields.mod ../include/futils.mod \
450 ../include/global_parameters.mod ../include/load_netcdf_module.mod \
451 ../include/nemo_states_module.mod ../include/physics_from_options.mod \
452- ../include/spud.mod ../include/tictoc.mod ../include/vtk_cache_module.mod
453+ ../include/samplenetcdf.mod ../include/spud.mod ../include/tictoc.mod \
454+ ../include/tidal_module.mod ../include/vtk_cache_module.mod
455
456 ../include/physics_from_options.mod: Physics_From_Options.o
457 @true
458
459=== modified file 'schemas/input_output.rnc'
460--- schemas/input_output.rnc 2012-02-11 14:10:31 +0000
461+++ schemas/input_output.rnc 2012-03-27 11:21:19 +0000
462@@ -35,7 +35,8 @@
463 element from_file {
464 attribute file_name { xsd:string },
465 (
466- vtu_input_format
467+ vtu_input_format|
468+ netcdf_input_format
469 ),
470 comment
471 }|
472@@ -575,9 +576,15 @@
473
474 netcdf_input_format =
475 (
476- ## NetCDF CF 1.4 (http://cf-pcmdi.llnl.gov/)
477+ ## Read from netcdf file
478 element format {
479- attribute name { "NetCDF - CF 1.x" },
480+ attribute name { "netcdf" },
481+ ## The field to read from the NetCDF file.
482+ element field_name {
483+ anystring,
484+ comment
485+ },
486 comment
487 }
488 )
489+
490
491=== modified file 'schemas/input_output.rng'
492--- schemas/input_output.rng 2012-02-11 14:10:31 +0000
493+++ schemas/input_output.rng 2012-03-27 11:21:19 +0000
494@@ -60,7 +60,10 @@
495 <attribute name="file_name">
496 <data type="string"/>
497 </attribute>
498- <ref name="vtu_input_format"/>
499+ <choice>
500+ <ref name="vtu_input_format"/>
501+ <ref name="netcdf_input_format"/>
502+ </choice>
503 <ref name="comment"/>
504 </element>
505 <element name="NEMO_data">
506@@ -638,10 +641,15 @@
507 </define>
508 <define name="netcdf_input_format">
509 <element name="format">
510- <a:documentation>NetCDF CF 1.4 (http://cf-pcmdi.llnl.gov/)</a:documentation>
511+ <a:documentation>Read from netcdf file</a:documentation>
512 <attribute name="name">
513- <value>NetCDF - CF 1.x</value>
514+ <value>netcdf</value>
515 </attribute>
516+ <element name="field_name">
517+ <a:documentation>The field to read from the NetCDF file.</a:documentation>
518+ <ref name="anystring"/>
519+ <ref name="comment"/>
520+ </element>
521 <ref name="comment"/>
522 </element>
523 </define>
524
525=== modified file 'schemas/prognostic_field_options.rnc'
526--- schemas/prognostic_field_options.rnc 2012-02-13 15:35:39 +0000
527+++ schemas/prognostic_field_options.rnc 2012-03-27 11:21:19 +0000
528@@ -1479,7 +1479,7 @@
529 ## Type
530 element type {
531 attribute name { "dirichlet" },
532- input_choice_real_plus_boundary_forcing
533+ input_choice_real_contents
534 }
535 }*,
536 prognostic_scalar_output_options,
537@@ -1511,7 +1511,7 @@
538 ## Type
539 element type {
540 attribute name { "dirichlet" },
541- input_choice_real_plus_boundary_forcing
542+ input_choice_real_contents
543 }
544 }+,
545 ## Disables checkpointing of this field
546@@ -1681,198 +1681,6 @@
547 interpolation_algorithm_scalar_full,
548 discrete_properties_algorithm_scalar?
549 )
550-
551-# free surface field, this is a copy of prognostic_scalar_field above
552-# removing all options that don't apply (mainly advection related)
553-prognostic_free_surface_field =
554- (
555- (
556- ## Spatial discretisation options
557- element spatial_discretisation {
558- ## Form a full 3D system for the free surface
559- element free_surface_3D {
560- empty
561- }?,
562- element fourth_order_dissipation {
563- empty
564- }?,
565- ## low order (linear) free surface
566- element low_order_free_surface {
567- empty
568- }?,
569- (
570- ## Select free surface filter
571- ##
572- ## With PN-PN we need some filter to supress spurious modes.
573- element default_free_surface_filter {
574- empty
575- }|
576- ## Select free surface filter
577- ##
578- ## With PN-PN we need some filter to supress spurious modes.
579- element user_specified_free_surface_filter {
580- ## Default is to apply 0.01 and for wetting and drying cases 1.0
581- element non_linear_filter_coefficient {
582- real
583- }
584- }|
585- ## Switch off free surface filter, this is more efficient than setting the coefficient to 0.
586- element switch_off_free_surface_filter {
587- empty
588- }
589- ),
590- ## Apply wetting and drying routines
591- element wetting_drying {
592- empty
593- }?,
594- ## Tidal forcing options
595- element tidal_forcing {
596- ## M2
597- element M2 {
598- empty
599- }?,
600- ## S2
601- element S2 {
602- empty
603- }?,
604- ## N2
605- element N2 {
606- empty
607- }?,
608- ## K2
609- element K2 {
610- empty
611- }?,
612- ## K1
613- element K1 {
614- empty
615- }?,
616- ## O1
617- element O1 {
618- empty
619- }?,
620- ## P1
621- element P1 {
622- empty
623- }?,
624- ## Q1
625- element Q1 {
626- empty
627- }?,
628- ## Switch on all tidal components
629- element all_tidal_components {
630- empty
631- }?,
632- ## Switches on a Love number of 0.3
633- element love_number {
634- empty
635- }?,
636- ## Use static tidal force for testing
637- element static_tidal_force {
638- empty
639- }?
640- }?
641- }
642- ),
643- # atheta, ctheta and fstheta (absorption, coriolis and free surface)
644- # need to go in temporal discretisation
645- # they are currently hard-coded however
646- element temporal_discretisation {
647- ## Implicit/explicitness for the free surface.
648- ##
649- ## Suggested value 1.0 (should be at least bigger than 0.5).
650- ## =0. -- explicit
651- ## =0.5 -- Crank-Nicolson
652- ## =1. -- implicit
653- element theta {
654- real
655- },
656- # Maybe this should go under a proper absorption field under free surface?
657- ## Implicit/explicitness for absorption
658- ## =0. -- explicit (default)
659- ## =0.5 -- Crank-Nicolson
660- ## =1. -- implicit
661- element absorption_theta {
662- real
663- }?
664- },
665- ## Solver
666- element solver {
667- linear_solver_options_sym
668- },
669- (
670- ## Initial condition for WholeMesh
671- ##
672- ## Only specify one condition if not using mesh regions.
673- ## Otherwise select other initial_condition option, specify region_ids
674- ## and distinct names. Then add extra intial conditions for other regions.
675- element initial_condition {
676- attribute name { "WholeMesh" },
677- input_choice_initial_condition_real
678- }|
679- ## Multiple initial_conditions are allowed if specifying
680- ## different values in different
681- ## regions of the mesh (defined by region_ids). In this case
682- ## each initial_condition
683- ## requires a distinct name for the options dictionary.
684- element initial_condition {
685- attribute name { string },
686- region_ids?,
687- input_choice_initial_condition_real
688- }
689- )+,
690- ## Boundary conditions
691- element boundary_conditions {
692- attribute name { string },
693- ## Surface id:
694- element surface_ids {
695- integer_vector
696- },
697- ## Type
698- (
699- element type {
700- attribute name { "dirichlet" },
701- (
702- input_choice_real_contents|
703- element from_file {
704- element tidal {
705- attribute file_name { string },
706- attribute variable_name_amplitude { string },
707- attribute variable_name_phase { string },
708- ## See E.W. Schwiderski - Rev. Geophys. Space
709- ## Phys. Vol. 18 No. 1 pp. 243--268, 1980
710- ## for details of these constituent.
711- attribute name {"M2"|"S2"|"N2"|"K2"|"K1"|"O1"|"P1"|"Q1"|"Mf"|"Mm"|"Ssa"}
712- }+
713- }|
714- ## Set the boundary free-surface height from NEMO data.
715- ## A prescribed NEMO pressure scalar field must be set to use this option.
716- ## Set the name of the prescribed NEMO pressure scalar field below.
717- element NEMO_data {
718- attribute field_name { string }
719- }
720- )
721- }|
722- element type {
723- attribute name { "neumann" },
724- input_choice_real
725- }|
726- robin_bc_scalar
727- )
728- }*,
729- # no Diffusivity for field
730- # no source term
731- # no Absorption term
732- # no Adaptive timestepping option
733- prognostic_scalar_output_options,
734- prognostic_scalar_stat_options,
735- scalar_convergence_options,
736- prognostic_detector_options,
737- scalar_steady_state_options,
738- adaptivity_options_prognostic_scalar_field,
739- interpolation_algorithm_scalar,
740- discrete_properties_algorithm_scalar?
741- )
742
743 # stream function, this is a copy of prognostic_scalar_field above
744 # removing all options that don't apply (mainly advection related)
745
746=== modified file 'schemas/prognostic_field_options.rng'
747--- schemas/prognostic_field_options.rng 2012-02-13 15:35:39 +0000
748+++ schemas/prognostic_field_options.rng 2012-03-27 11:21:19 +0000
749@@ -1807,7 +1807,7 @@
750 <attribute name="name">
751 <value>dirichlet</value>
752 </attribute>
753- <ref name="input_choice_real_plus_boundary_forcing"/>
754+ <ref name="input_choice_real_contents"/>
755 </element>
756 </element>
757 </zeroOrMore>
758@@ -1847,7 +1847,7 @@
759 <attribute name="name">
760 <value>dirichlet</value>
761 </attribute>
762- <ref name="input_choice_real_plus_boundary_forcing"/>
763+ <ref name="input_choice_real_contents"/>
764 </element>
765 </element>
766 </oneOrMore>
767@@ -2048,276 +2048,6 @@
768 </optional>
769 </define>
770 <!--
771- free surface field, this is a copy of prognostic_scalar_field above
772- removing all options that don't apply (mainly advection related)
773- -->
774- <define name="prognostic_free_surface_field">
775- <element name="spatial_discretisation">
776- <a:documentation>Spatial discretisation options</a:documentation>
777- <optional>
778- <element name="free_surface_3D">
779- <a:documentation>Form a full 3D system for the free surface</a:documentation>
780- <empty/>
781- </element>
782- </optional>
783- <optional>
784- <element name="fourth_order_dissipation">
785- <empty/>
786- </element>
787- </optional>
788- <optional>
789- <element name="low_order_free_surface">
790- <a:documentation>low order (linear) free surface</a:documentation>
791- <empty/>
792- </element>
793- </optional>
794- <choice>
795- <element name="default_free_surface_filter">
796- <a:documentation>Select free surface filter
797-
798-With PN-PN we need some filter to supress spurious modes.</a:documentation>
799- <empty/>
800- </element>
801- <element name="user_specified_free_surface_filter">
802- <a:documentation>Select free surface filter
803-
804-With PN-PN we need some filter to supress spurious modes.</a:documentation>
805- <element name="non_linear_filter_coefficient">
806- <a:documentation>Default is to apply 0.01 and for wetting and drying cases 1.0</a:documentation>
807- <ref name="real"/>
808- </element>
809- </element>
810- <element name="switch_off_free_surface_filter">
811- <a:documentation>Switch off free surface filter, this is more efficient than setting the coefficient to 0.</a:documentation>
812- <empty/>
813- </element>
814- </choice>
815- <optional>
816- <element name="wetting_drying">
817- <a:documentation>Apply wetting and drying routines</a:documentation>
818- <empty/>
819- </element>
820- </optional>
821- <optional>
822- <element name="tidal_forcing">
823- <a:documentation>Tidal forcing options </a:documentation>
824- <optional>
825- <element name="M2">
826- <a:documentation>M2</a:documentation>
827- <empty/>
828- </element>
829- </optional>
830- <optional>
831- <element name="S2">
832- <a:documentation>S2</a:documentation>
833- <empty/>
834- </element>
835- </optional>
836- <optional>
837- <element name="N2">
838- <a:documentation>N2</a:documentation>
839- <empty/>
840- </element>
841- </optional>
842- <optional>
843- <element name="K2">
844- <a:documentation>K2</a:documentation>
845- <empty/>
846- </element>
847- </optional>
848- <optional>
849- <element name="K1">
850- <a:documentation>K1</a:documentation>
851- <empty/>
852- </element>
853- </optional>
854- <optional>
855- <element name="O1">
856- <a:documentation>O1</a:documentation>
857- <empty/>
858- </element>
859- </optional>
860- <optional>
861- <element name="P1">
862- <a:documentation>P1</a:documentation>
863- <empty/>
864- </element>
865- </optional>
866- <optional>
867- <element name="Q1">
868- <a:documentation>Q1</a:documentation>
869- <empty/>
870- </element>
871- </optional>
872- <optional>
873- <element name="all_tidal_components">
874- <a:documentation>Switch on all tidal components</a:documentation>
875- <empty/>
876- </element>
877- </optional>
878- <optional>
879- <element name="love_number">
880- <a:documentation>Switches on a Love number of 0.3</a:documentation>
881- <empty/>
882- </element>
883- </optional>
884- <optional>
885- <element name="static_tidal_force">
886- <a:documentation>Use static tidal force for testing</a:documentation>
887- <empty/>
888- </element>
889- </optional>
890- </element>
891- </optional>
892- </element>
893- <!--
894- atheta, ctheta and fstheta (absorption, coriolis and free surface)
895- need to go in temporal discretisation
896- they are currently hard-coded however
897- -->
898- <element name="temporal_discretisation">
899- <element name="theta">
900- <a:documentation>Implicit/explicitness for the free surface.
901-
902-Suggested value 1.0 (should be at least bigger than 0.5).
903- =0. -- explicit
904- =0.5 -- Crank-Nicolson
905- =1. -- implicit</a:documentation>
906- <ref name="real"/>
907- </element>
908- <optional>
909- <!-- Maybe this should go under a proper absorption field under free surface? -->
910- <element name="absorption_theta">
911- <a:documentation>Implicit/explicitness for absorption
912-=0. -- explicit (default)
913-=0.5 -- Crank-Nicolson
914-=1. -- implicit</a:documentation>
915- <ref name="real"/>
916- </element>
917- </optional>
918- </element>
919- <element name="solver">
920- <a:documentation>Solver</a:documentation>
921- <ref name="linear_solver_options_sym"/>
922- </element>
923- <oneOrMore>
924- <choice>
925- <element name="initial_condition">
926- <a:documentation>Initial condition for WholeMesh
927-
928-Only specify one condition if not using mesh regions.
929-Otherwise select other initial_condition option, specify region_ids
930-and distinct names. Then add extra intial conditions for other regions.</a:documentation>
931- <attribute name="name">
932- <value>WholeMesh</value>
933- </attribute>
934- <ref name="input_choice_initial_condition_real"/>
935- </element>
936- <element name="initial_condition">
937- <a:documentation>Multiple initial_conditions are allowed if specifying
938-different values in different
939-regions of the mesh (defined by region_ids). In this case
940-each initial_condition
941-requires a distinct name for the options dictionary.</a:documentation>
942- <attribute name="name">
943- <data type="string" datatypeLibrary=""/>
944- </attribute>
945- <optional>
946- <ref name="region_ids"/>
947- </optional>
948- <ref name="input_choice_initial_condition_real"/>
949- </element>
950- </choice>
951- </oneOrMore>
952- <zeroOrMore>
953- <element name="boundary_conditions">
954- <a:documentation>Boundary conditions</a:documentation>
955- <attribute name="name">
956- <data type="string" datatypeLibrary=""/>
957- </attribute>
958- <element name="surface_ids">
959- <a:documentation>Surface id:</a:documentation>
960- <ref name="integer_vector"/>
961- </element>
962- <choice>
963- <a:documentation>Type</a:documentation>
964- <element name="type">
965- <attribute name="name">
966- <value>dirichlet</value>
967- </attribute>
968- <choice>
969- <ref name="input_choice_real_contents"/>
970- <element name="from_file">
971- <oneOrMore>
972- <element name="tidal">
973- <attribute name="file_name">
974- <data type="string" datatypeLibrary=""/>
975- </attribute>
976- <attribute name="variable_name_amplitude">
977- <data type="string" datatypeLibrary=""/>
978- </attribute>
979- <attribute name="variable_name_phase">
980- <data type="string" datatypeLibrary=""/>
981- </attribute>
982- <attribute name="name">
983- <a:documentation>See E.W. Schwiderski - Rev. Geophys. Space
984-Phys. Vol. 18 No. 1 pp. 243--268, 1980
985-for details of these constituent.</a:documentation>
986- <choice>
987- <value>M2</value>
988- <value>S2</value>
989- <value>N2</value>
990- <value>K2</value>
991- <value>K1</value>
992- <value>O1</value>
993- <value>P1</value>
994- <value>Q1</value>
995- <value>Mf</value>
996- <value>Mm</value>
997- <value>Ssa</value>
998- </choice>
999- </attribute>
1000- </element>
1001- </oneOrMore>
1002- </element>
1003- <element name="NEMO_data">
1004- <a:documentation>Set the boundary free-surface height from NEMO data.
1005-A prescribed NEMO pressure scalar field must be set to use this option.
1006-Set the name of the prescribed NEMO pressure scalar field below.</a:documentation>
1007- <attribute name="field_name">
1008- <data type="string" datatypeLibrary=""/>
1009- </attribute>
1010- </element>
1011- </choice>
1012- </element>
1013- <element name="type">
1014- <attribute name="name">
1015- <value>neumann</value>
1016- </attribute>
1017- <ref name="input_choice_real"/>
1018- </element>
1019- <ref name="robin_bc_scalar"/>
1020- </choice>
1021- </element>
1022- </zeroOrMore>
1023- <!--
1024- no Diffusivity for field
1025- no source term
1026- no Absorption term
1027- no Adaptive timestepping option
1028- -->
1029- <ref name="prognostic_scalar_output_options"/>
1030- <ref name="prognostic_scalar_stat_options"/>
1031- <ref name="scalar_convergence_options"/>
1032- <ref name="prognostic_detector_options"/>
1033- <ref name="scalar_steady_state_options"/>
1034- <ref name="adaptivity_options_prognostic_scalar_field"/>
1035- <ref name="interpolation_algorithm_scalar"/>
1036- <optional>
1037- <ref name="discrete_properties_algorithm_scalar"/>
1038- </optional>
1039- </define>
1040- <!--
1041 stream function, this is a copy of prognostic_scalar_field above
1042 removing all options that don't apply (mainly advection related)
1043 -->
1044
1045=== modified file 'schemas/shallow_water_options.rnc'
1046--- schemas/shallow_water_options.rnc 2011-10-19 17:43:54 +0000
1047+++ schemas/shallow_water_options.rnc 2012-03-27 11:21:19 +0000
1048@@ -1909,18 +1909,6 @@
1049 attribute name { "FreeSurface" },
1050 (
1051 ## Free Surface
1052- ## NOTE: the prognostic FreeSurface field only works with the
1053- ## legacy_continuous_galerkin code path
1054- element prognostic {
1055- ## Note that this is not the quadratic mesh balance pressure is
1056- ## actually calculated on, but the linear mesh it is projected back
1057- ## on for output purposes.
1058- element mesh {
1059- attribute name { "VelocityMesh" }
1060- },
1061- prognostic_free_surface_field
1062- }|
1063- ## Free Surface
1064 ## NOTE: the diagnostic FreeSurface field only works in combination
1065 ## with the free_surface boundary condition applied to the Velocity
1066 ## field. It gives you a 3D field (constant over the vertical)
1067
1068=== modified file 'schemas/shallow_water_options.rng'
1069--- schemas/shallow_water_options.rng 2011-10-19 17:43:54 +0000
1070+++ schemas/shallow_water_options.rng 2012-03-27 11:21:19 +0000
1071@@ -2215,42 +2215,26 @@
1072 <attribute name="name">
1073 <value>FreeSurface</value>
1074 </attribute>
1075- <choice>
1076- <element name="prognostic">
1077- <a:documentation>Free Surface
1078-NOTE: the prognostic FreeSurface field only works with the
1079-legacy_continuous_galerkin code path</a:documentation>
1080- <element name="mesh">
1081- <a:documentation>Note that this is not the quadratic mesh balance pressure is
1082-actually calculated on, but the linear mesh it is projected back
1083-on for output purposes.</a:documentation>
1084- <attribute name="name">
1085- <value>VelocityMesh</value>
1086- </attribute>
1087- </element>
1088- <ref name="prognostic_free_surface_field"/>
1089- </element>
1090- <element name="diagnostic">
1091- <a:documentation>Free Surface
1092+ <element name="diagnostic">
1093+ <a:documentation>Free Surface
1094 NOTE: the diagnostic FreeSurface field only works in combination
1095 with the free_surface boundary condition applied to the Velocity
1096 field. It gives you a 3D field (constant over the vertical)
1097 of the free surface elevation.</a:documentation>
1098- <ref name="internal_algorithm"/>
1099- <!--
1100- this is hard-coded on the PressureMesh as long as the Pressure is
1101- if this is no longer true, it should be option-checked to be on the
1102- same mesh as Pressure
1103- -->
1104- <element name="mesh">
1105- <a:documentation>Must be on the same mesh as Pressure</a:documentation>
1106- <attribute name="name">
1107- <value>PressureMesh</value>
1108- </attribute>
1109- </element>
1110- <ref name="diagnostic_scalar_field"/>
1111+ <ref name="internal_algorithm"/>
1112+ <!--
1113+ this is hard-coded on the PressureMesh as long as the Pressure is
1114+ if this is no longer true, it should be option-checked to be on the
1115+ same mesh as Pressure
1116+ -->
1117+ <element name="mesh">
1118+ <a:documentation>Must be on the same mesh as Pressure</a:documentation>
1119+ <attribute name="name">
1120+ <value>PressureMesh</value>
1121+ </attribute>
1122 </element>
1123- </choice>
1124+ <ref name="diagnostic_scalar_field"/>
1125+ </element>
1126 </element>
1127 <element name="scalar_field">
1128 <a:documentation>Second Fluid</a:documentation>
1129
1130=== modified file 'schemas/test_advection_diffusion_options.rnc'
1131--- schemas/test_advection_diffusion_options.rnc 2011-10-19 17:43:54 +0000
1132+++ schemas/test_advection_diffusion_options.rnc 2012-03-27 11:21:19 +0000
1133@@ -1755,235 +1755,6 @@
1134 discrete_properties_algorithm_scalar?
1135 )
1136
1137-# free surface field, this is a copy of prognostic_scalar_field above
1138-# removing all options that don't apply (mainly advection related)
1139-prognostic_free_surface_field =
1140- (
1141- (
1142- ## Spatial discretisation options
1143- element spatial_discretisation {
1144- ## Form a full 3D system for the free surface
1145- element free_surface_3D {
1146- empty
1147- }?,
1148- element fourth_order_dissipation {
1149- empty
1150- }?,
1151- ## low order (linear) free surface
1152- element low_order_free_surface {
1153- empty
1154- }?,
1155- (
1156- ## Select free surface filter
1157- ##
1158- ## With PN-PN we need some filter to supress spurious modes.
1159- element default_free_surface_filter {
1160- empty
1161- }|
1162- ## Select free surface filter
1163- ##
1164- ## With PN-PN we need some filter to supress spurious modes.
1165- element user_specified_free_surface_filter {
1166- ## Default is to apply 0.01 and for wetting and drying cases 1.0
1167- element non_linear_filter_coefficient {
1168- real
1169- }
1170- }|
1171- ## Switch off free surface filter, this is more efficient than setting the coefficient to 0.
1172- element switch_off_free_surface_filter {
1173- empty
1174- }
1175- ),
1176- ## Apply wetting and drying routines
1177- element wetting_drying {
1178- empty
1179- }?,
1180- ## Tidal forcing options
1181- element tidal_forcing {
1182- ## M2
1183- element M2 {
1184- empty
1185- }?,
1186- ## S2
1187- element S2 {
1188- empty
1189- }?,
1190- ## N2
1191- element N2 {
1192- empty
1193- }?,
1194- ## K2
1195- element K2 {
1196- empty
1197- }?,
1198- ## K1
1199- element K1 {
1200- empty
1201- }?,
1202- ## O1
1203- element O1 {
1204- empty
1205- }?,
1206- ## P1
1207- element P1 {
1208- empty
1209- }?,
1210- ## Q1
1211- element Q1 {
1212- empty
1213- }?,
1214- ## Switch on all tidal components
1215- element all_tidal_components {
1216- empty
1217- }?,
1218- ## Switches on a Love number of 0.3
1219- element love_number {
1220- empty
1221- }?,
1222- ## Use static tidal force for testing
1223- element static_tidal_force {
1224- empty
1225- }?
1226- }?
1227- }|
1228- ## Legacy Free Surface
1229- ## Allows astronomical forcing for multiple tidal constituents.
1230- ## Integer should be sum of desired components as follows:
1231- ##
1232- ## 3D Free Surface = 1
1233- ##
1234- ## Fourth Order Dissipation = 4
1235- ##
1236- ## Low Order Free Surface = 8
1237- ##
1238- ## Implicit absorption in the free surface (good for wetting/drying) = 16
1239- ##
1240- ## Turn on all tides = 32
1241- ##
1242- ## Love Number = 64
1243- ##
1244- ## Static Tidal Force = 128
1245- ##
1246- ## M2 constituent = 2048
1247- ##
1248- ## S2 constituent = 4096
1249- ##
1250- ## N2 constituent = 8192
1251- ##
1252- ## K2 constituent = 16384
1253- ##
1254- ## K1 constituent = 32768
1255- ##
1256- ## O1 constituent = 65536
1257- ##
1258- ## P1 constituent = 131072
1259- ##
1260- ## Q1 constituent = 262144
1261- element Legacy_Free_Surface {
1262- integer
1263- }
1264- ),
1265- # atheta, ctheta and fstheta (absorption, coriolis and free surface)
1266- # need to go in temporal discretisation
1267- # they are currently hard-coded however
1268- element temporal_discretisation {
1269- ## Implicit/explicitness for the free surface.
1270- ##
1271- ## Suggested value 1.0 (should be at least bigger than 0.5).
1272- ## =0. -- explicit
1273- ## =0.5 -- Crank-Nicolson
1274- ## =1. -- implicit
1275- element theta {
1276- real
1277- },
1278- # Maybe this should go under a proper absorption field under free surface?
1279- ## Implicit/explicitness for absorption
1280- ## =0. -- explicit (default)
1281- ## =0.5 -- Crank-Nicolson
1282- ## =1. -- implicit
1283- element absorption_theta {
1284- real
1285- }?
1286- },
1287- ## Solver
1288- element solver {
1289- linear_solver_options_sym
1290- },
1291- (
1292- ## Initial condition for WholeMesh
1293- ##
1294- ## Only specify one condition if not using mesh regions.
1295- ## Otherwise select other initial_condition option, specify region_ids
1296- ## and distinct names. Then add extra intial conditions for other regions.
1297- element initial_condition {
1298- attribute name { "WholeMesh" },
1299- input_choice_initial_condition_real
1300- }|
1301- ## Multiple initial_conditions are allowed if specifying
1302- ## different values in different
1303- ## regions of the mesh (defined by region_ids). In this case
1304- ## each initial_condition
1305- ## requires a distinct name for the options dictionary.
1306- element initial_condition {
1307- attribute name { string },
1308- region_ids,
1309- input_choice_initial_condition_real
1310- }
1311- )+,
1312- ## Boundary conditions
1313- element boundary_conditions {
1314- attribute name { string },
1315- ## Surface id:
1316- element surface_ids {
1317- integer_vector
1318- },
1319- ## Type
1320- (
1321- element type {
1322- attribute name { "dirichlet" },
1323- (
1324- input_choice_real_contents|
1325- element from_file {
1326- element tidal {
1327- attribute file_name { string },
1328- attribute variable_name_amplitude { string },
1329- attribute variable_name_phase { string },
1330- ## See E.W. Schwiderski - Rev. Geophys. Space
1331- ## Phys. Vol. 18 No. 1 pp. 243--268, 1980
1332- ## for details of these constituent.
1333- attribute name {"M2"|"S2"|"N2"|"K2"|"K1"|"O1"|"P1"|"Q1"|"Mf"|"Mm"|"Ssa"}
1334- }+
1335- }
1336- )
1337- }|
1338- element type {
1339- attribute name { "neumann" },
1340- input_choice_real
1341- }|
1342- element type {
1343- attribute name { "robin" },
1344- element order_zero_coefficient {
1345- input_choice_real
1346- },
1347- element order_one_coefficient {
1348- input_choice_real
1349- }
1350- }
1351- )
1352- }*,
1353- # no Diffusivity for field
1354- # no source term
1355- # no Absorption term
1356- # no Adaptive timestepping option
1357- prognostic_scalar_output_options,
1358- prognostic_scalar_stat_options,
1359- scalar_convergence_options,
1360- prognostic_detector_options,
1361- scalar_steady_state_options,
1362- adaptivity_options_prognostic_scalar_field,
1363- interpolation_algorithm_scalar,
1364- discrete_properties_algorithm_scalar?
1365- )
1366
1367 # stream function, this is a copy of prognostic_scalar_field above
1368 # removing all options that don't apply (mainly advection related)
1369@@ -3345,18 +3116,6 @@
1370 attribute name { "FreeSurface" },
1371 (
1372 ## Free Surface
1373- ## NOTE: the prognostic FreeSurface field only works with the
1374- ## legacy_continuous_galerkin code path
1375- element prognostic {
1376- ## Note that this is not the quadratic mesh balance pressure is
1377- ## actually calculated on, but the linear mesh it is projected back
1378- ## on for output purposes.
1379- element mesh {
1380- attribute name { "VelocityMesh" }
1381- },
1382- prognostic_free_surface_field
1383- }|
1384- ## Free Surface
1385 ## NOTE: the diagnostic FreeSurface field only works in combination
1386 ## with the free_surface boundary condition applied to the Velocity
1387 ## field. It gives you a 3D field (constant over the vertical)
1388
1389=== modified file 'schemas/test_advection_diffusion_options.rng'
1390--- schemas/test_advection_diffusion_options.rng 2011-10-19 17:43:54 +0000
1391+++ schemas/test_advection_diffusion_options.rng 2012-03-27 11:21:19 +0000
1392@@ -2075,314 +2075,6 @@
1393 </optional>
1394 </define>
1395 <!--
1396- free surface field, this is a copy of prognostic_scalar_field above
1397- removing all options that don't apply (mainly advection related)
1398- -->
1399- <define name="prognostic_free_surface_field">
1400- <choice>
1401- <element name="spatial_discretisation">
1402- <a:documentation>Spatial discretisation options</a:documentation>
1403- <optional>
1404- <element name="free_surface_3D">
1405- <a:documentation>Form a full 3D system for the free surface</a:documentation>
1406- <empty/>
1407- </element>
1408- </optional>
1409- <optional>
1410- <element name="fourth_order_dissipation">
1411- <empty/>
1412- </element>
1413- </optional>
1414- <optional>
1415- <element name="low_order_free_surface">
1416- <a:documentation>low order (linear) free surface</a:documentation>
1417- <empty/>
1418- </element>
1419- </optional>
1420- <choice>
1421- <element name="default_free_surface_filter">
1422- <a:documentation>Select free surface filter
1423-
1424-With PN-PN we need some filter to supress spurious modes.</a:documentation>
1425- <empty/>
1426- </element>
1427- <element name="user_specified_free_surface_filter">
1428- <a:documentation>Select free surface filter
1429-
1430-With PN-PN we need some filter to supress spurious modes.</a:documentation>
1431- <element name="non_linear_filter_coefficient">
1432- <a:documentation>Default is to apply 0.01 and for wetting and drying cases 1.0</a:documentation>
1433- <ref name="real"/>
1434- </element>
1435- </element>
1436- <element name="switch_off_free_surface_filter">
1437- <a:documentation>Switch off free surface filter, this is more efficient than setting the coefficient to 0.</a:documentation>
1438- <empty/>
1439- </element>
1440- </choice>
1441- <optional>
1442- <element name="wetting_drying">
1443- <a:documentation>Apply wetting and drying routines</a:documentation>
1444- <empty/>
1445- </element>
1446- </optional>
1447- <optional>
1448- <element name="tidal_forcing">
1449- <a:documentation>Tidal forcing options </a:documentation>
1450- <optional>
1451- <element name="M2">
1452- <a:documentation>M2</a:documentation>
1453- <empty/>
1454- </element>
1455- </optional>
1456- <optional>
1457- <element name="S2">
1458- <a:documentation>S2</a:documentation>
1459- <empty/>
1460- </element>
1461- </optional>
1462- <optional>
1463- <element name="N2">
1464- <a:documentation>N2</a:documentation>
1465- <empty/>
1466- </element>
1467- </optional>
1468- <optional>
1469- <element name="K2">
1470- <a:documentation>K2</a:documentation>
1471- <empty/>
1472- </element>
1473- </optional>
1474- <optional>
1475- <element name="K1">
1476- <a:documentation>K1</a:documentation>
1477- <empty/>
1478- </element>
1479- </optional>
1480- <optional>
1481- <element name="O1">
1482- <a:documentation>O1</a:documentation>
1483- <empty/>
1484- </element>
1485- </optional>
1486- <optional>
1487- <element name="P1">
1488- <a:documentation>P1</a:documentation>
1489- <empty/>
1490- </element>
1491- </optional>
1492- <optional>
1493- <element name="Q1">
1494- <a:documentation>Q1</a:documentation>
1495- <empty/>
1496- </element>
1497- </optional>
1498- <optional>
1499- <element name="all_tidal_components">
1500- <a:documentation>Switch on all tidal components</a:documentation>
1501- <empty/>
1502- </element>
1503- </optional>
1504- <optional>
1505- <element name="love_number">
1506- <a:documentation>Switches on a Love number of 0.3</a:documentation>
1507- <empty/>
1508- </element>
1509- </optional>
1510- <optional>
1511- <element name="static_tidal_force">
1512- <a:documentation>Use static tidal force for testing</a:documentation>
1513- <empty/>
1514- </element>
1515- </optional>
1516- </element>
1517- </optional>
1518- </element>
1519- <element name="Legacy_Free_Surface">
1520- <a:documentation>Legacy Free Surface
1521-Allows astronomical forcing for multiple tidal constituents.
1522-Integer should be sum of desired components as follows:
1523-
1524-3D Free Surface = 1
1525-
1526-Fourth Order Dissipation = 4
1527-
1528-Low Order Free Surface = 8
1529-
1530-Implicit absorption in the free surface (good for wetting/drying) = 16
1531-
1532-Turn on all tides = 32
1533-
1534-Love Number = 64
1535-
1536-Static Tidal Force = 128
1537-
1538-M2 constituent = 2048
1539-
1540-S2 constituent = 4096
1541-
1542-N2 constituent = 8192
1543-
1544-K2 constituent = 16384
1545-
1546-K1 constituent = 32768
1547-
1548-O1 constituent = 65536
1549-
1550-P1 constituent = 131072
1551-
1552-Q1 constituent = 262144</a:documentation>
1553- <ref name="integer"/>
1554- </element>
1555- </choice>
1556- <!--
1557- atheta, ctheta and fstheta (absorption, coriolis and free surface)
1558- need to go in temporal discretisation
1559- they are currently hard-coded however
1560- -->
1561- <element name="temporal_discretisation">
1562- <element name="theta">
1563- <a:documentation>Implicit/explicitness for the free surface.
1564-
1565-Suggested value 1.0 (should be at least bigger than 0.5).
1566- =0. -- explicit
1567- =0.5 -- Crank-Nicolson
1568- =1. -- implicit</a:documentation>
1569- <ref name="real"/>
1570- </element>
1571- <optional>
1572- <!-- Maybe this should go under a proper absorption field under free surface? -->
1573- <element name="absorption_theta">
1574- <a:documentation>Implicit/explicitness for absorption
1575-=0. -- explicit (default)
1576-=0.5 -- Crank-Nicolson
1577-=1. -- implicit</a:documentation>
1578- <ref name="real"/>
1579- </element>
1580- </optional>
1581- </element>
1582- <element name="solver">
1583- <a:documentation>Solver</a:documentation>
1584- <ref name="linear_solver_options_sym"/>
1585- </element>
1586- <oneOrMore>
1587- <choice>
1588- <element name="initial_condition">
1589- <a:documentation>Initial condition for WholeMesh
1590-
1591-Only specify one condition if not using mesh regions.
1592-Otherwise select other initial_condition option, specify region_ids
1593-and distinct names. Then add extra intial conditions for other regions.</a:documentation>
1594- <attribute name="name">
1595- <value>WholeMesh</value>
1596- </attribute>
1597- <ref name="input_choice_initial_condition_real"/>
1598- </element>
1599- <element name="initial_condition">
1600- <a:documentation>Multiple initial_conditions are allowed if specifying
1601-different values in different
1602-regions of the mesh (defined by region_ids). In this case
1603-each initial_condition
1604-requires a distinct name for the options dictionary.</a:documentation>
1605- <attribute name="name">
1606- <data type="string" datatypeLibrary=""/>
1607- </attribute>
1608- <ref name="region_ids"/>
1609- <ref name="input_choice_initial_condition_real"/>
1610- </element>
1611- </choice>
1612- </oneOrMore>
1613- <zeroOrMore>
1614- <element name="boundary_conditions">
1615- <a:documentation>Boundary conditions</a:documentation>
1616- <attribute name="name">
1617- <data type="string" datatypeLibrary=""/>
1618- </attribute>
1619- <element name="surface_ids">
1620- <a:documentation>Surface id:</a:documentation>
1621- <ref name="integer_vector"/>
1622- </element>
1623- <choice>
1624- <a:documentation>Type</a:documentation>
1625- <element name="type">
1626- <attribute name="name">
1627- <value>dirichlet</value>
1628- </attribute>
1629- <choice>
1630- <ref name="input_choice_real_contents"/>
1631- <element name="from_file">
1632- <oneOrMore>
1633- <element name="tidal">
1634- <attribute name="file_name">
1635- <data type="string" datatypeLibrary=""/>
1636- </attribute>
1637- <attribute name="variable_name_amplitude">
1638- <data type="string" datatypeLibrary=""/>
1639- </attribute>
1640- <attribute name="variable_name_phase">
1641- <data type="string" datatypeLibrary=""/>
1642- </attribute>
1643- <attribute name="name">
1644- <a:documentation>See E.W. Schwiderski - Rev. Geophys. Space
1645-Phys. Vol. 18 No. 1 pp. 243--268, 1980
1646-for details of these constituent.</a:documentation>
1647- <choice>
1648- <value>M2</value>
1649- <value>S2</value>
1650- <value>N2</value>
1651- <value>K2</value>
1652- <value>K1</value>
1653- <value>O1</value>
1654- <value>P1</value>
1655- <value>Q1</value>
1656- <value>Mf</value>
1657- <value>Mm</value>
1658- <value>Ssa</value>
1659- </choice>
1660- </attribute>
1661- </element>
1662- </oneOrMore>
1663- </element>
1664- </choice>
1665- </element>
1666- <element name="type">
1667- <attribute name="name">
1668- <value>neumann</value>
1669- </attribute>
1670- <ref name="input_choice_real"/>
1671- </element>
1672- <element name="type">
1673- <attribute name="name">
1674- <value>robin</value>
1675- </attribute>
1676- <element name="order_zero_coefficient">
1677- <ref name="input_choice_real"/>
1678- </element>
1679- <element name="order_one_coefficient">
1680- <ref name="input_choice_real"/>
1681- </element>
1682- </element>
1683- </choice>
1684- </element>
1685- </zeroOrMore>
1686- <!--
1687- no Diffusivity for field
1688- no source term
1689- no Absorption term
1690- no Adaptive timestepping option
1691- -->
1692- <ref name="prognostic_scalar_output_options"/>
1693- <ref name="prognostic_scalar_stat_options"/>
1694- <ref name="scalar_convergence_options"/>
1695- <ref name="prognostic_detector_options"/>
1696- <ref name="scalar_steady_state_options"/>
1697- <ref name="adaptivity_options_prognostic_scalar_field"/>
1698- <ref name="interpolation_algorithm_scalar"/>
1699- <optional>
1700- <ref name="discrete_properties_algorithm_scalar"/>
1701- </optional>
1702- </define>
1703- <!--
1704 stream function, this is a copy of prognostic_scalar_field above
1705 removing all options that don't apply (mainly advection related)
1706 -->
1707@@ -3943,42 +3635,26 @@
1708 <attribute name="name">
1709 <value>FreeSurface</value>
1710 </attribute>
1711- <choice>
1712- <element name="prognostic">
1713- <a:documentation>Free Surface
1714-NOTE: the prognostic FreeSurface field only works with the
1715-legacy_continuous_galerkin code path</a:documentation>
1716- <element name="mesh">
1717- <a:documentation>Note that this is not the quadratic mesh balance pressure is
1718-actually calculated on, but the linear mesh it is projected back
1719-on for output purposes.</a:documentation>
1720- <attribute name="name">
1721- <value>VelocityMesh</value>
1722- </attribute>
1723- </element>
1724- <ref name="prognostic_free_surface_field"/>
1725- </element>
1726- <element name="diagnostic">
1727- <a:documentation>Free Surface
1728+ <element name="diagnostic">
1729+ <a:documentation>Free Surface
1730 NOTE: the diagnostic FreeSurface field only works in combination
1731 with the free_surface boundary condition applied to the Velocity
1732 field. It gives you a 3D field (constant over the vertical)
1733 of the free surface elevation.</a:documentation>
1734- <ref name="internal_algorithm"/>
1735- <!--
1736- this is hard-coded on the PressureMesh as long as the Pressure is
1737- if this is no longer true, it should be option-checked to be on the
1738- same mesh as Pressure
1739- -->
1740- <element name="mesh">
1741- <a:documentation>Must be on the same mesh as Pressure</a:documentation>
1742- <attribute name="name">
1743- <value>PressureMesh</value>
1744- </attribute>
1745- </element>
1746- <ref name="diagnostic_scalar_field"/>
1747+ <ref name="internal_algorithm"/>
1748+ <!--
1749+ this is hard-coded on the PressureMesh as long as the Pressure is
1750+ if this is no longer true, it should be option-checked to be on the
1751+ same mesh as Pressure
1752+ -->
1753+ <element name="mesh">
1754+ <a:documentation>Must be on the same mesh as Pressure</a:documentation>
1755+ <attribute name="name">
1756+ <value>PressureMesh</value>
1757+ </attribute>
1758 </element>
1759- </choice>
1760+ <ref name="diagnostic_scalar_field"/>
1761+ </element>
1762 </element>
1763 <element name="scalar_field">
1764 <a:documentation>Second Fluid</a:documentation>
1765
1766=== added directory 'tests/sample_netcdf_test'
1767=== added file 'tests/sample_netcdf_test/Makefile'
1768--- tests/sample_netcdf_test/Makefile 1970-01-01 00:00:00 +0000
1769+++ tests/sample_netcdf_test/Makefile 2012-03-27 11:21:19 +0000
1770@@ -0,0 +1,9 @@
1771+input: clean
1772+ ./create_netcdf_test.py
1773+ gmsh -2 src/box_on_sphere.geo -o box_on_sphere.msh
1774+ ../../bin/gmsh2triangle box_on_sphere.msh
1775+ sed -i '1s/ 3 / 2 /' box_on_sphere.node
1776+
1777+clean:
1778+ rm -f box_on_sphere.* fluidity.* netcdf_test.nc
1779+ rm -f sample*.vtu sample.stat matrixdump*
1780
1781=== added file 'tests/sample_netcdf_test/create_netcdf_test.py'
1782--- tests/sample_netcdf_test/create_netcdf_test.py 1970-01-01 00:00:00 +0000
1783+++ tests/sample_netcdf_test/create_netcdf_test.py 2012-03-27 11:21:19 +0000
1784@@ -0,0 +1,70 @@
1785+#!/usr/bin/env python
1786+from math import cos, sin, pi
1787+
1788+lonl=-10.0
1789+lonr=0.0
1790+lonres=0.5
1791+latl=40.0
1792+latr=60.0
1793+latres=0.5
1794+
1795+
1796+# the following 3 functions will also be used from the fluidity run:
1797+# made up tidal amplitude
1798+def amplitude(lon, lat):
1799+ return cos(pi*4*lon/180)*sin(pi*4*lat/180)
1800+
1801+# made up phase (contains 360 degree line within domain)
1802+def phase(lon,lat):
1803+ ph= ((latl+latr)/2.0-lat)*10
1804+ if lat<(latl+latr)/2.0:
1805+ return ph
1806+ else:
1807+ return ph+360
1808+
1809+# auxillary function to compute lon,lat from xyz (taken from fluidity code)
1810+def lonlat(xyz):
1811+ from math import pi,atan2,sqrt,acos
1812+ r=sqrt(xyz[0]**2+xyz[1]**2+xyz[2]**2)
1813+ lon=180.0/pi*atan2(xyz[1],xyz[0])
1814+ lat=90.0-180.0/pi*acos(xyz[2]/r)
1815+ return lon,lat
1816+
1817+# add a field (variable) to the netcdf file
1818+def add_field(nc, name, dims, val):
1819+ import numpy
1820+ nc.createVariable(name, 'f', dims)
1821+ var=nc.variables[name]
1822+ # make sure to cast to numpy array of float type
1823+ val=numpy.array(val, dtype='float32')
1824+ var[:]=val
1825+ var.long_name=name
1826+ var.actual_range=(val.min(), val.max())
1827+
1828+def create_netcdf(filename):
1829+ from Scientific.IO.NetCDF import NetCDFFile
1830+ from numpy import arange
1831+ nc=NetCDFFile(filename, 'w')
1832+ lonrange=arange(lonl,lonr+lonres/10.,lonres,dtype='float32')
1833+ latrange=arange(latl,latr+latres/10.,latres,dtype='float32')
1834+ nc.createDimension('longitude', len(lonrange))
1835+ nc.createDimension('latitude', len(latrange))
1836+
1837+ # add the variables
1838+ add_field(nc, 'longitude', ('longitude',), lonrange)
1839+ add_field(nc, 'latitude', ('latitude',), latrange)
1840+ # note that fields have to be f(lat,lon) as this a hard-coded assumption
1841+ # in our NetCDF reader
1842+ add_field(nc, 'amplitude', ('latitude','longitude'),
1843+ [[amplitude(lon,lat) for lon in lonrange] for lat in latrange])
1844+ add_field(nc, 'phase', ('latitude','longitude'),
1845+ [[phase(lon,lat) for lon in lonrange] for lat in latrange])
1846+
1847+ # finally set some global attributes
1848+ nc.Conventions='COARDS/CF-1.0'
1849+ nc.history='Test netCDF file created with create_netcdf_test.py script'
1850+
1851+ nc.close()
1852+
1853+if __name__ == "__main__":
1854+ create_netcdf('netcdf_test.nc')
1855
1856=== added file 'tests/sample_netcdf_test/sample.flml'
1857--- tests/sample_netcdf_test/sample.flml 1970-01-01 00:00:00 +0000
1858+++ tests/sample_netcdf_test/sample.flml 2012-03-27 11:21:19 +0000
1859@@ -0,0 +1,658 @@
1860+<?xml version='1.0' encoding='utf-8'?>
1861+<fluidity_options>
1862+ <simulation_name>
1863+ <string_value lines="1">sample</string_value>
1864+ </simulation_name>
1865+ <problem_type>
1866+ <string_value lines="1">oceans</string_value>
1867+ </problem_type>
1868+ <geometry>
1869+ <dimension>
1870+ <integer_value rank="0">3</integer_value>
1871+ </dimension>
1872+ <mesh name="CoordinateMesh">
1873+ <from_mesh>
1874+ <mesh name="InputMesh"/>
1875+ <extrude>
1876+ <regions name="WholeMesh">
1877+ <bottom_depth>
1878+ <constant>
1879+ <real_value rank="0">200</real_value>
1880+ </constant>
1881+ </bottom_depth>
1882+ <sizing_function>
1883+ <constant>
1884+ <real_value rank="0">10000</real_value>
1885+ </constant>
1886+ </sizing_function>
1887+ <top_surface_id>
1888+ <integer_value rank="0">1</integer_value>
1889+ </top_surface_id>
1890+ <bottom_surface_id>
1891+ <integer_value rank="0">2</integer_value>
1892+ </bottom_surface_id>
1893+ </regions>
1894+ </extrude>
1895+ <stat>
1896+ <exclude_from_stat/>
1897+ </stat>
1898+ </from_mesh>
1899+ </mesh>
1900+ <mesh name="VelocityMesh">
1901+ <from_mesh>
1902+ <mesh name="CoordinateMesh"/>
1903+ <mesh_continuity>
1904+ <string_value>discontinuous</string_value>
1905+ </mesh_continuity>
1906+ <stat>
1907+ <exclude_from_stat/>
1908+ </stat>
1909+ </from_mesh>
1910+ </mesh>
1911+ <mesh name="PressureMesh">
1912+ <from_mesh>
1913+ <mesh name="CoordinateMesh"/>
1914+ <mesh_shape>
1915+ <polynomial_degree>
1916+ <integer_value rank="0">2</integer_value>
1917+ </polynomial_degree>
1918+ </mesh_shape>
1919+ <stat>
1920+ <exclude_from_stat/>
1921+ </stat>
1922+ </from_mesh>
1923+ </mesh>
1924+ <mesh name="InputMesh">
1925+ <from_file file_name="box_on_sphere">
1926+ <format name="triangle"/>
1927+ <stat>
1928+ <include_in_stat/>
1929+ </stat>
1930+ </from_file>
1931+ </mesh>
1932+ <quadrature>
1933+ <degree>
1934+ <integer_value rank="0">4</integer_value>
1935+ </degree>
1936+ </quadrature>
1937+ <spherical_earth>
1938+ <linear_mapping/>
1939+ </spherical_earth>
1940+ <ocean_boundaries>
1941+ <top_surface_ids>
1942+ <integer_value shape="1" rank="1">1</integer_value>
1943+ </top_surface_ids>
1944+ <bottom_surface_ids>
1945+ <integer_value shape="1" rank="1">2</integer_value>
1946+ </bottom_surface_ids>
1947+ <scalar_field name="DistanceToTop" rank="0">
1948+ <diagnostic>
1949+ <algorithm name="Internal" material_phase_support="multiple"/>
1950+ <mesh name="CoordinateMesh"/>
1951+ <output/>
1952+ <stat/>
1953+ <convergence>
1954+ <include_in_convergence/>
1955+ </convergence>
1956+ <detectors>
1957+ <include_in_detectors/>
1958+ </detectors>
1959+ <steady_state>
1960+ <include_in_steady_state/>
1961+ </steady_state>
1962+ </diagnostic>
1963+ </scalar_field>
1964+ <scalar_field name="DistanceToBottom" rank="0">
1965+ <diagnostic>
1966+ <algorithm name="Internal" material_phase_support="multiple"/>
1967+ <mesh name="CoordinateMesh"/>
1968+ <output/>
1969+ <stat/>
1970+ <convergence>
1971+ <include_in_convergence/>
1972+ </convergence>
1973+ <detectors>
1974+ <include_in_detectors/>
1975+ </detectors>
1976+ <steady_state>
1977+ <include_in_steady_state/>
1978+ </steady_state>
1979+ </diagnostic>
1980+ </scalar_field>
1981+ </ocean_boundaries>
1982+ </geometry>
1983+ <io>
1984+ <dump_format>
1985+ <string_value>vtk</string_value>
1986+ </dump_format>
1987+ <dump_period_in_timesteps>
1988+ <constant>
1989+ <integer_value rank="0">1</integer_value>
1990+ </constant>
1991+ </dump_period_in_timesteps>
1992+ <output_mesh name="VelocityMesh"/>
1993+ <stat/>
1994+ </io>
1995+ <timestepping>
1996+ <current_time>
1997+ <real_value rank="0">0</real_value>
1998+ <time_units date="seconds since 1987-01-05 00:00.0"/>
1999+ </current_time>
2000+ <timestep>
2001+ <real_value rank="0">1200</real_value>
2002+ </timestep>
2003+ <finish_time>
2004+ <real_value rank="0">86400</real_value>
2005+ </finish_time>
2006+ <final_timestep>
2007+ <integer_value rank="0">10</integer_value>
2008+ </final_timestep>
2009+ <nonlinear_iterations>
2010+ <integer_value rank="0">2</integer_value>
2011+ </nonlinear_iterations>
2012+ </timestepping>
2013+ <physical_parameters>
2014+ <gravity>
2015+ <magnitude>
2016+ <real_value rank="0">9.81</real_value>
2017+ </magnitude>
2018+ <vector_field name="GravityDirection" rank="1">
2019+ <prescribed>
2020+ <mesh name="CoordinateMesh"/>
2021+ <value name="WholeMesh">
2022+ <python>
2023+ <string_value lines="20" type="python">def val(X, t):
2024+
2025+ a = X[0]
2026+ b = X[1]
2027+ c = X[2]
2028+
2029+ x_component = -(a/((a**2+b**2+c**2)**0.5))
2030+ y_component = -(b/((a**2+b**2+c**2)**0.5))
2031+ z_component = -(c/((a**2+b**2+c**2)**0.5))
2032+
2033+ return [x_component, y_component, z_component]</string_value>
2034+ </python>
2035+ </value>
2036+ <output/>
2037+ <stat>
2038+ <include_in_stat/>
2039+ </stat>
2040+ <detectors>
2041+ <exclude_from_detectors/>
2042+ </detectors>
2043+ </prescribed>
2044+ </vector_field>
2045+ </gravity>
2046+ <coriolis>
2047+ <on_sphere>
2048+ <omega>
2049+ <real_value rank="0">7.27220522e-5</real_value>
2050+ </omega>
2051+ </on_sphere>
2052+ </coriolis>
2053+ </physical_parameters>
2054+ <material_phase name="Ocean">
2055+ <equation_of_state>
2056+ <fluids>
2057+ <linear>
2058+ <reference_density>
2059+ <real_value rank="0">1</real_value>
2060+ </reference_density>
2061+ <subtract_out_hydrostatic_level/>
2062+ </linear>
2063+ </fluids>
2064+ </equation_of_state>
2065+ <scalar_field name="Pressure" rank="0">
2066+ <prognostic>
2067+ <mesh name="PressureMesh"/>
2068+ <spatial_discretisation>
2069+ <continuous_galerkin>
2070+ <remove_stabilisation_term/>
2071+ <integrate_continuity_by_parts/>
2072+ </continuous_galerkin>
2073+ </spatial_discretisation>
2074+ <scheme>
2075+ <poisson_pressure_solution>
2076+ <string_value lines="1">only first timestep</string_value>
2077+ </poisson_pressure_solution>
2078+ <use_projection_method/>
2079+ </scheme>
2080+ <solver>
2081+ <iterative_method name="cg"/>
2082+ <preconditioner name="mg">
2083+ <vertical_lumping/>
2084+ </preconditioner>
2085+ <relative_error>
2086+ <real_value rank="0">1.0e-7</real_value>
2087+ </relative_error>
2088+ <max_iterations>
2089+ <integer_value rank="0">1700</integer_value>
2090+ </max_iterations>
2091+ <never_ignore_solver_failures/>
2092+ <diagnostics>
2093+ <monitors/>
2094+ </diagnostics>
2095+ </solver>
2096+ <initial_condition name="WholeMesh">
2097+ <constant>
2098+ <real_value rank="0">0.0</real_value>
2099+ </constant>
2100+ </initial_condition>
2101+ <boundary_conditions name="BoundaryTide">
2102+ <surface_ids>
2103+ <integer_value shape="4" rank="1">1009 1010 1011 1012</integer_value>
2104+ </surface_ids>
2105+ <type name="dirichlet">
2106+ <from_file>
2107+ <tidal file_name="netcdf_test.nc" variable_name_amplitude="amplitude" name="M2" variable_name_phase="phase"/>
2108+ </from_file>
2109+ </type>
2110+ </boundary_conditions>
2111+ <output/>
2112+ <stat/>
2113+ <convergence>
2114+ <include_in_convergence/>
2115+ </convergence>
2116+ <detectors>
2117+ <exclude_from_detectors/>
2118+ </detectors>
2119+ <steady_state>
2120+ <include_in_steady_state/>
2121+ </steady_state>
2122+ <consistent_interpolation/>
2123+ </prognostic>
2124+ </scalar_field>
2125+ <vector_field name="Velocity" rank="1">
2126+ <prognostic>
2127+ <mesh name="VelocityMesh"/>
2128+ <equation name="Boussinesq"/>
2129+ <spatial_discretisation>
2130+ <discontinuous_galerkin>
2131+ <mass_terms/>
2132+ <viscosity_scheme>
2133+ <compact_discontinuous_galerkin/>
2134+ </viscosity_scheme>
2135+ <advection_scheme>
2136+ <upwind/>
2137+ <project_velocity_to_continuous>
2138+ <mesh name="CoordinateMesh"/>
2139+ </project_velocity_to_continuous>
2140+ <integrate_advection_by_parts>
2141+ <twice/>
2142+ </integrate_advection_by_parts>
2143+ </advection_scheme>
2144+ </discontinuous_galerkin>
2145+ <conservative_advection>
2146+ <real_value rank="0">0.0</real_value>
2147+ </conservative_advection>
2148+ </spatial_discretisation>
2149+ <temporal_discretisation>
2150+ <theta>
2151+ <real_value rank="0">0.5</real_value>
2152+ </theta>
2153+ <relaxation>
2154+ <real_value rank="0">0.5</real_value>
2155+ </relaxation>
2156+ <theta_divergence>
2157+ <real_value rank="0">1.0</real_value>
2158+ </theta_divergence>
2159+ <discontinuous_galerkin>
2160+ <maximum_courant_number_per_subcycle>
2161+ <real_value rank="0">0.1</real_value>
2162+ </maximum_courant_number_per_subcycle>
2163+ </discontinuous_galerkin>
2164+ </temporal_discretisation>
2165+ <solver>
2166+ <iterative_method name="gmres">
2167+ <restart>
2168+ <integer_value rank="0">30</integer_value>
2169+ </restart>
2170+ </iterative_method>
2171+ <preconditioner name="sor"/>
2172+ <relative_error>
2173+ <real_value rank="0">1.0e-7</real_value>
2174+ </relative_error>
2175+ <max_iterations>
2176+ <integer_value rank="0">10000</integer_value>
2177+ </max_iterations>
2178+ <never_ignore_solver_failures/>
2179+ <diagnostics>
2180+ <monitors/>
2181+ </diagnostics>
2182+ </solver>
2183+ <initial_condition name="WholeMesh">
2184+ <constant>
2185+ <real_value shape="3" dim1="dim" rank="1">0.0 0.0 0.0</real_value>
2186+ </constant>
2187+ </initial_condition>
2188+ <boundary_conditions name="drag_on_bottom_and_sides">
2189+ <surface_ids>
2190+ <integer_value shape="5" rank="1">2 1009 1010 1011 1012</integer_value>
2191+ </surface_ids>
2192+ <type name="drag">
2193+ <constant>
2194+ <real_value rank="0">0.0025</real_value>
2195+ </constant>
2196+ <quadratic_drag/>
2197+ </type>
2198+ </boundary_conditions>
2199+ <boundary_conditions name="FreeSurface">
2200+ <surface_ids>
2201+ <integer_value shape="1" rank="1">1</integer_value>
2202+ </surface_ids>
2203+ <type name="free_surface"/>
2204+ </boundary_conditions>
2205+ <boundary_conditions name="NoNormalFlow">
2206+ <surface_ids>
2207+ <integer_value shape="5" rank="1">2 1009 1010 1011 1012</integer_value>
2208+ </surface_ids>
2209+ <type name="no_normal_flow"/>
2210+ </boundary_conditions>
2211+ <tensor_field name="Viscosity" rank="2">
2212+ <prescribed>
2213+ <value name="WholeMesh">
2214+ <anisotropic_symmetric>
2215+ <python>
2216+ <string_value lines="20" type="python">def val(X, t):
2217+ a = X[0]
2218+ b = X[1]
2219+ c = X[2]
2220+ from math import sqrt, sin, cos, atan2, acos
2221+ r=sqrt(a**2+b**2+c**2)
2222+ A1=200.0
2223+ A2=A1
2224+ A3=0.1
2225+ phi=atan2(b,a)
2226+ theta=acos(c/r)
2227+ T11=A1*sin(phi)**2+A2*cos(theta)**2*cos(phi)**2+A3*sin(theta)**2*cos(phi)**2
2228+ T12=-A1*sin(phi)*cos(phi)+A2*cos(theta)**2*sin(phi)*cos(phi)+A3*sin(theta)**2*sin(phi)*cos(phi)
2229+ T13=-A2*sin(theta)*cos(theta)*cos(phi)+A3*sin(theta)*cos(theta)*cos(phi)
2230+ T21=T12
2231+ T22=A1*cos(phi)**2+A2*cos(theta)**2*sin(phi)**2+A3*sin(theta)**2*sin(phi)**2
2232+ T23=-A2*sin(theta)*cos(theta)*sin(phi)+A3*sin(theta)*cos(theta)*sin(phi)
2233+ T31=T13
2234+ T32=T23
2235+ T33=A2*sin(theta)**2+A3*cos(theta)**2
2236+
2237+ return [[T11, T12, T13],
2238+ [T21, T22, T23],
2239+ [T31, T32, T33]]</string_value>
2240+ </python>
2241+ </anisotropic_symmetric>
2242+ </value>
2243+ <output/>
2244+ </prescribed>
2245+ </tensor_field>
2246+ <output/>
2247+ <stat>
2248+ <include_in_stat/>
2249+ <previous_time_step>
2250+ <exclude_from_stat/>
2251+ </previous_time_step>
2252+ <nonlinear_field>
2253+ <exclude_from_stat/>
2254+ </nonlinear_field>
2255+ </stat>
2256+ <convergence>
2257+ <include_in_convergence/>
2258+ </convergence>
2259+ <detectors>
2260+ <include_in_detectors/>
2261+ </detectors>
2262+ <steady_state>
2263+ <include_in_steady_state/>
2264+ </steady_state>
2265+ <consistent_interpolation/>
2266+ </prognostic>
2267+ </vector_field>
2268+ <scalar_field name="DG_CourantNumber" rank="0">
2269+ <diagnostic>
2270+ <algorithm name="Internal" material_phase_support="multiple"/>
2271+ <mesh name="VelocityMesh"/>
2272+ <output/>
2273+ <stat/>
2274+ <convergence>
2275+ <include_in_convergence/>
2276+ </convergence>
2277+ <detectors>
2278+ <include_in_detectors/>
2279+ </detectors>
2280+ <steady_state>
2281+ <include_in_steady_state/>
2282+ </steady_state>
2283+ </diagnostic>
2284+ </scalar_field>
2285+ <scalar_field name="Amplitude" rank="0">
2286+ <prescribed>
2287+ <mesh name="VelocityMesh"/>
2288+ <value name="WholeMesh">
2289+ <from_file file_name="netcdf_test.nc">
2290+ <format name="netcdf">
2291+ <field_name>
2292+ <string_value lines="1">amplitude</string_value>
2293+ </field_name>
2294+ </format>
2295+ </from_file>
2296+ </value>
2297+ <output/>
2298+ <stat/>
2299+ <detectors>
2300+ <exclude_from_detectors/>
2301+ </detectors>
2302+ </prescribed>
2303+ </scalar_field>
2304+ <scalar_field name="AmplitudeFromPython" rank="0">
2305+ <diagnostic>
2306+ <algorithm name="scalar_python_diagnostic" material_phase_support="single">
2307+ <string_value lines="20" type="python">from create_netcdf_test import amplitude,lonlat
2308+x=state.vector_fields['DiagnosticCoordinate']
2309+for i,xyz in enumerate(x.val):
2310+ lon,lat=lonlat(xyz)
2311+ field.set(i, amplitude(lon,lat))</string_value>
2312+ <depends>
2313+ <string_value lines="1">DiagnosticCoordinate</string_value>
2314+ </depends>
2315+ </algorithm>
2316+ <mesh name="PressureMesh"/>
2317+ <output/>
2318+ <stat/>
2319+ <convergence>
2320+ <include_in_convergence/>
2321+ </convergence>
2322+ <detectors>
2323+ <include_in_detectors/>
2324+ </detectors>
2325+ <steady_state>
2326+ <include_in_steady_state/>
2327+ </steady_state>
2328+ </diagnostic>
2329+ </scalar_field>
2330+ <scalar_field name="AmplitudeDifference" rank="0">
2331+ <diagnostic>
2332+ <algorithm name="scalar_difference" source_field_1_name="Amplitude" source_field_2_name="AmplitudeFromPython" source_field_2_type="scalar" material_phase_support="single" source_field_1_type="scalar">
2333+ <absolute_difference/>
2334+ </algorithm>
2335+ <mesh name="VelocityMesh"/>
2336+ <output/>
2337+ <stat/>
2338+ <convergence>
2339+ <include_in_convergence/>
2340+ </convergence>
2341+ <detectors>
2342+ <include_in_detectors/>
2343+ </detectors>
2344+ <steady_state>
2345+ <include_in_steady_state/>
2346+ </steady_state>
2347+ </diagnostic>
2348+ </scalar_field>
2349+ <scalar_field name="TideFromPython" rank="0">
2350+ <diagnostic>
2351+ <algorithm name="scalar_python_diagnostic" material_phase_support="single">
2352+ <string_value type="python" lines="20">from create_netcdf_test import amplitude,lonlat,phase
2353+from math import cos,pi
2354+g=9.81 # gravity
2355+omega=1.40519E-04 # M2 frequency (taken from code)
2356+x=state.vector_fields['DiagnosticCoordinate']
2357+for i,xyz in enumerate(x.val):
2358+ lon,lat=lonlat(xyz)
2359+ A=amplitude(lon,lat)
2360+ alpha=phase(lon,lat)
2361+ field.set(i, g*A*cos(omega*time+pi*alpha/180.0))</string_value>
2362+ <depends>
2363+ <string_value lines="1">DiagnosticCoordinate</string_value>
2364+ </depends>
2365+ </algorithm>
2366+ <mesh name="PressureMesh"/>
2367+ <output/>
2368+ <stat/>
2369+ <convergence>
2370+ <include_in_convergence/>
2371+ </convergence>
2372+ <detectors>
2373+ <include_in_detectors/>
2374+ </detectors>
2375+ <steady_state>
2376+ <include_in_steady_state/>
2377+ </steady_state>
2378+ </diagnostic>
2379+ </scalar_field>
2380+ <scalar_field name="TidalDifference" rank="0">
2381+ <diagnostic>
2382+ <algorithm name="scalar_difference" source_field_1_name="Pressure" source_field_2_name="TideFromPython" source_field_2_type="scalar" material_phase_support="single" source_field_1_type="scalar">
2383+ <absolute_difference/>
2384+ </algorithm>
2385+ <mesh name="PressureMesh"/>
2386+ <output/>
2387+ <stat/>
2388+ <convergence>
2389+ <include_in_convergence/>
2390+ </convergence>
2391+ <detectors>
2392+ <include_in_detectors/>
2393+ </detectors>
2394+ <steady_state>
2395+ <include_in_steady_state/>
2396+ </steady_state>
2397+ </diagnostic>
2398+ </scalar_field>
2399+ <scalar_field name="BoundaryMask" rank="0">
2400+ <prognostic>
2401+ <mesh name="PressureMesh"/>
2402+ <equation name="AdvectionDiffusion"/>
2403+ <spatial_discretisation>
2404+ <continuous_galerkin>
2405+ <stabilisation>
2406+ <no_stabilisation/>
2407+ </stabilisation>
2408+ <advection_terms>
2409+ <exclude_advection_terms/>
2410+ </advection_terms>
2411+ <mass_terms/>
2412+ </continuous_galerkin>
2413+ <conservative_advection>
2414+ <real_value rank="0">0.0</real_value>
2415+ </conservative_advection>
2416+ </spatial_discretisation>
2417+ <temporal_discretisation>
2418+ <theta>
2419+ <real_value rank="0">0.0</real_value>
2420+ </theta>
2421+ </temporal_discretisation>
2422+ <solver>
2423+ <iterative_method name="gmres">
2424+ <restart>
2425+ <integer_value rank="0">30</integer_value>
2426+ </restart>
2427+ </iterative_method>
2428+ <preconditioner name="sor"/>
2429+ <relative_error>
2430+ <real_value rank="0">1e-7</real_value>
2431+ </relative_error>
2432+ <absolute_error>
2433+ <real_value rank="0">0.1</real_value>
2434+ </absolute_error>
2435+ <max_iterations>
2436+ <integer_value rank="0">1000</integer_value>
2437+ </max_iterations>
2438+ <never_ignore_solver_failures/>
2439+ <diagnostics>
2440+ <monitors/>
2441+ </diagnostics>
2442+ </solver>
2443+ <initial_condition name="WholeMesh">
2444+ <constant>
2445+ <real_value rank="0">0.0</real_value>
2446+ </constant>
2447+ </initial_condition>
2448+ <boundary_conditions name="AllSides">
2449+ <surface_ids>
2450+ <integer_value shape="4" rank="1">1009 1010 1011 1012</integer_value>
2451+ </surface_ids>
2452+ <type name="dirichlet">
2453+ <constant>
2454+ <real_value rank="0">1.0</real_value>
2455+ </constant>
2456+ </type>
2457+ </boundary_conditions>
2458+ <output/>
2459+ <stat/>
2460+ <convergence>
2461+ <include_in_convergence/>
2462+ </convergence>
2463+ <detectors>
2464+ <include_in_detectors/>
2465+ </detectors>
2466+ <steady_state>
2467+ <include_in_steady_state/>
2468+ </steady_state>
2469+ <consistent_interpolation/>
2470+ </prognostic>
2471+ </scalar_field>
2472+ <scalar_field name="TidalDifferenceMasked" rank="0">
2473+ <diagnostic>
2474+ <algorithm name="scalar_python_diagnostic" material_phase_support="single">
2475+ <string_value type="python" lines="20">diff=state.scalar_fields['TidalDifference']
2476+# this field is 1 on the boundary nodes, and 0 in the interior
2477+mask=state.scalar_fields['BoundaryMask']
2478+field.val[:]=diff.val*mask.val</string_value>
2479+ <depends>
2480+ <string_value lines="1">BoundaryMask,TidalDifference</string_value>
2481+ </depends>
2482+ </algorithm>
2483+ <mesh name="PressureMesh"/>
2484+ <output/>
2485+ <stat/>
2486+ <convergence>
2487+ <include_in_convergence/>
2488+ </convergence>
2489+ <detectors>
2490+ <include_in_detectors/>
2491+ </detectors>
2492+ <steady_state>
2493+ <include_in_steady_state/>
2494+ </steady_state>
2495+ </diagnostic>
2496+ </scalar_field>
2497+ <vector_field name="DiagnosticCoordinate" rank="1">
2498+ <diagnostic>
2499+ <algorithm name="Internal" material_phase_support="multiple"/>
2500+ <mesh name="PressureMesh"/>
2501+ <output/>
2502+ <stat>
2503+ <include_in_stat/>
2504+ </stat>
2505+ <convergence>
2506+ <include_in_convergence/>
2507+ </convergence>
2508+ <detectors>
2509+ <include_in_detectors/>
2510+ </detectors>
2511+ <steady_state>
2512+ <include_in_steady_state/>
2513+ </steady_state>
2514+ </diagnostic>
2515+ </vector_field>
2516+ </material_phase>
2517+</fluidity_options>
2518
2519=== added file 'tests/sample_netcdf_test/sample_netcdf_test.xml'
2520--- tests/sample_netcdf_test/sample_netcdf_test.xml 1970-01-01 00:00:00 +0000
2521+++ tests/sample_netcdf_test/sample_netcdf_test.xml 2012-03-27 11:21:19 +0000
2522@@ -0,0 +1,24 @@
2523+<?xml version='1.0' encoding='utf-8'?>
2524+<testproblem>
2525+ <name>sample_netcdf_test</name>
2526+ <owner userid="skramer"/>
2527+ <problem_definition length="short" nprocs="1">
2528+ <command_line>fluidity -v2 -l sample.flml</command_line>
2529+ </problem_definition>
2530+ <variables>
2531+ <variable name="amplitude_difference_max" language="python"> from fluidity_tools import stat_parser
2532+stat=stat_parser('sample.stat')
2533+amplitude_difference_max=stat['Ocean']['AmplitudeDifference']['max']</variable>
2534+ <variable name="tidal_difference_max" language="python">from fluidity_tools import stat_parser
2535+stat=stat_parser('sample.stat')
2536+tidal_difference_max=stat['Ocean']['TidalDifferenceMasked']['max']</variable>
2537+ </variables>
2538+ <pass_tests>
2539+ <test name="compare_amplitude_from_netCDF_with_function" language="python"># compare difference between amplitude read from netCDF
2540+# with values from python function used to create this netCDF file
2541+assert( max(amplitude_difference_max)&lt;3e-4 )</test>
2542+ <test name="compare_tidal_boundary_value_with_python" language="python"># compare values of tidal boundary condition on Pressure
2543+# with those directly computed from python functions
2544+assert( max(tidal_difference_max)&lt;0.01 )</test>
2545+ </pass_tests>
2546+</testproblem>
2547
2548=== added directory 'tests/sample_netcdf_test/src'
2549=== added file 'tests/sample_netcdf_test/src/box_on_sphere.geo'
2550--- tests/sample_netcdf_test/src/box_on_sphere.geo 1970-01-01 00:00:00 +0000
2551+++ tests/sample_netcdf_test/src/box_on_sphere.geo 2012-03-27 11:21:19 +0000
2552@@ -0,0 +1,17 @@
2553+Include "shorelines_with_boundaries.geo";
2554+
2555+Printf("Assigning characteristic mesh sizes...");
2556+Field[ IFI + 1] = MathEval;
2557+Field[ IFI + 1].F = "50000";
2558+
2559+Background Field = IFI + 1;
2560+
2561+// Dont extent the elements sizes from the boundary inside the domain
2562+Mesh.CharacteristicLengthExtendFromBoundary = 0;
2563+
2564+//Set some options for better png output
2565+General.Color.Background = {255,255,255};
2566+General.Color.BackgroundGradient = {255,255,255};
2567+General.Color.Foreground = Black;
2568+Mesh.Color.Lines = {0,0,0};
2569+
2570
2571=== added file 'tests/sample_netcdf_test/src/definitions.geo'
2572--- tests/sample_netcdf_test/src/definitions.geo 1970-01-01 00:00:00 +0000
2573+++ tests/sample_netcdf_test/src/definitions.geo 2012-03-27 11:21:19 +0000
2574@@ -0,0 +1,41 @@
2575+Printf("Reading function and point definitions...");
2576+
2577+Function DrawParallel
2578+ alpha = parallelSectionStartingY/parallelSectionStartingX;
2579+ parallelRadius = Sqrt(parallelSectionStartingX^2 + parallelSectionStartingY^2);
2580+ deltaAlpha = (parallelSectionEndingY/parallelSectionEndingX - parallelSectionStartingY/parallelSectionStartingX)/pointsOnParallel;
2581+ For t In {1:pointsOnParallel}
2582+ alpha += deltaAlpha;
2583+ newParallelPointX = (parallelSectionStartingX/Fabs(parallelSectionStartingX))*parallelRadius/(Sqrt(alpha^2 + 1));
2584+ newParallelPointY = newParallelPointX*alpha;
2585+ newPointOnParallel = newp; Point(newPointOnParallel) = {newParallelPointX, newParallelPointY, 0};
2586+ EndFor
2587+ BSpline(newParallelID) = {firstPointOnParallel, newPointOnParallel-(pointsOnParallel-1):newPointOnParallel, lastPointOnParallel};
2588+Return
2589+
2590+//The coordinates of various points on the Surface of the Earth are converted to radians
2591+//and stereographic coordinatesbelow.
2592+
2593+//Point A is located 2 deg 00'W, 48 deg 45'N.
2594+Point_A_longitude_rad = -(2 + (00/60))*(Pi/180);
2595+Point_A_latitude_rad = (48 + (45/60))*(Pi/180);
2596+Point_A_stereographic_x = -Cos(Fabs(Point_A_longitude_rad))*Cos(Fabs(Point_A_latitude_rad))/( 1 + Sin(Fabs(Point_A_latitude_rad)) );
2597+Point_A_stereographic_y = Cos(Fabs(Point_A_latitude_rad))*Sin(Fabs(Point_A_longitude_rad))/( 1 + Sin(Fabs(Point_A_latitude_rad)) );
2598+
2599+//Point B is located at 9 deg 46'W, 48 deg 45'N
2600+Point_B_longitude_rad = -(9 + (46/60))*(Pi/180);
2601+Point_B_latitude_rad = (48 + (45/60))*(Pi/180);
2602+Point_B_stereographic_x = -Cos(Fabs(Point_B_longitude_rad))*Cos(Fabs(Point_B_latitude_rad))/( 1 + Sin(Fabs(Point_B_latitude_rad)) );
2603+Point_B_stereographic_y = Cos(Fabs(Point_B_latitude_rad))*Sin(Fabs(Point_B_longitude_rad))/( 1 + Sin(Fabs(Point_B_latitude_rad)) );
2604+
2605+//Point C is located at 9 deg 45'W, 56 deg 45'N
2606+Point_C_longitude_rad = -(9 + (45/60))*(Pi/180);
2607+Point_C_latitude_rad = (56 + (45/60))*(Pi/180);
2608+Point_C_stereographic_x = -Cos(Fabs(Point_C_longitude_rad))*Cos(Fabs(Point_C_latitude_rad))/( 1 + Sin(Fabs(Point_C_latitude_rad)) );
2609+Point_C_stereographic_y = Cos(Fabs(Point_C_latitude_rad))*Sin(Fabs(Point_C_longitude_rad))/( 1 + Sin(Fabs(Point_C_latitude_rad)) );
2610+
2611+//Point D is located at 2 deg 00'W, 56 deg 45'N
2612+Point_D_longitude_rad = -(2 + (00/60))*(Pi/180);
2613+Point_D_latitude_rad = (56 + (45/60))*(Pi/180);
2614+Point_D_stereographic_x = -Cos(Fabs(Point_D_longitude_rad))*Cos(Fabs(Point_D_latitude_rad))/( 1 + Sin(Fabs(Point_D_latitude_rad)) );
2615+Point_D_stereographic_y = Cos(Fabs(Point_D_latitude_rad))*Sin(Fabs(Point_D_longitude_rad))/( 1 + Sin(Fabs(Point_D_latitude_rad)) );
2616
2617=== added file 'tests/sample_netcdf_test/src/shorelines.geo'
2618--- tests/sample_netcdf_test/src/shorelines.geo 1970-01-01 00:00:00 +0000
2619+++ tests/sample_netcdf_test/src/shorelines.geo 2012-03-27 11:21:19 +0000
2620@@ -0,0 +1,8 @@
2621+IP = newp;
2622+IL = newl;
2623+ILL = newll;
2624+IS = news;
2625+IFI = newf;
2626+Point ( IP + 0 ) = {0, 0, 0 };
2627+Point ( IP + 1 ) = {0, 0,6.37101e+06};
2628+PolarSphere ( IS + 0 ) = {IP , IP+1};
2629
2630=== added file 'tests/sample_netcdf_test/src/shorelines_with_boundaries.geo'
2631--- tests/sample_netcdf_test/src/shorelines_with_boundaries.geo 1970-01-01 00:00:00 +0000
2632+++ tests/sample_netcdf_test/src/shorelines_with_boundaries.geo 2012-03-27 11:21:19 +0000
2633@@ -0,0 +1,46 @@
2634+Include "definitions.geo";
2635+Include "shorelines.geo";
2636+Coherence;
2637+
2638+Printf("Creating Meridian & Parallel segments to close the domain...");
2639+//So far, only points on the shorelies and curves approximating shorelines have been
2640+//constructed. we now add points in the sea, to close the domain boundaries
2641+Point(IP + 60000) = {Point_A_stereographic_x, Point_A_stereographic_y, 0};
2642+Point(IP + 60001) = {Point_B_stereographic_x, Point_B_stereographic_y, 0};
2643+Point(IP + 60002) = {Point_C_stereographic_x, Point_C_stereographic_y, 0};
2644+Point(IP + 60003) = {Point_D_stereographic_x, Point_D_stereographic_y, 0};
2645+
2646+//Draw South-most parallel of the Domain.
2647+pointsOnParallel = 200; //Assign parameters to variables and then call function DrawParallel,
2648+parallelSectionStartingX = Point_A_stereographic_x;
2649+parallelSectionStartingY = Point_A_stereographic_y;
2650+firstPointOnParallel = IP + 60000;
2651+parallelSectionEndingX = Point_B_stereographic_x;
2652+parallelSectionEndingY = Point_B_stereographic_y;
2653+lastPointOnParallel = IP + 60001;
2654+newParallelID = IL + 1000;
2655+Call DrawParallel;
2656+
2657+BSpline(IL + 1001) = {IP + 60001, IP + 60002};
2658+BSpline(IL + 1002) = {IP + 60000, IP + 60003};
2659+
2660+////Draw North-most parallel of the Domain.
2661+pointsOnParallel = 200; //Assign parameters to variables and then call function DrawParallel,
2662+parallelSectionStartingX = Point_C_stereographic_x;
2663+parallelSectionStartingY = Point_C_stereographic_y;
2664+firstPointOnParallel = IP + 60002;
2665+parallelSectionEndingX = Point_D_stereographic_x;
2666+parallelSectionEndingY = Point_D_stereographic_y;
2667+lastPointOnParallel = IP + 60003;
2668+newParallelID = IL + 1003;
2669+Call DrawParallel;
2670+
2671+Printf("Declaring surface on sphere to be meshed...");
2672+Line Loop(1006) = {1003, -1004, -1002, -1001};
2673+Plane Surface(1007) = {1006};
2674+Physical Surface(1008) = {1007};
2675+
2676+Physical Line(1009) = {1001}; //Physical line corresponding to south-most parallel.
2677+Physical Line(1010) = {1002}; //Physical line corresponding to meridian segment through point A.
2678+Physical Line(1011) = {1003}; //Physical line corresponding to meridian segment through point B.
2679+Physical Line(1012) = {1004}; //Physical line corresponding to north-most parallel.