Merge lp:~fluidity-core/fluidity/freesurfacefromnetcdffix into lp:fluidity

Proposed by Adam Candy
Status: Superseded
Proposed branch: lp:~fluidity-core/fluidity/freesurfacefromnetcdffix
Merge into: lp:fluidity
Diff against target: 1259 lines (+1052/-37)
15 files modified
manual/configuring_fluidity.tex (+15/-3)
ocean_forcing/load_netcdf.F90 (+20/-12)
preprocessor/Initialise_Fields.F90 (+2/-0)
schemas/input_output.rnc (+13/-7)
schemas/input_output.rng (+15/-15)
tests/netcdf_read_errors/Makefile (+18/-0)
tests/netcdf_read_errors/createnetcdf.py (+86/-0)
tests/netcdf_read_errors/missingdata.err.sample (+44/-0)
tests/netcdf_read_errors/netcdf_read_errors.xml (+130/-0)
tests/netcdf_read_errors/valid.flml (+292/-0)
tests/netcdf_read_free_surface/Makefile (+13/-0)
tests/netcdf_read_free_surface/createnetcdf.py (+33/-0)
tests/netcdf_read_free_surface/height.py (+13/-0)
tests/netcdf_read_free_surface/netcdf_read_free_surface.flml (+309/-0)
tests/netcdf_read_free_surface/netcdf_read_free_surface.xml (+49/-0)
To merge this branch: bzr merge lp:~fluidity-core/fluidity/freesurfacefromnetcdffix
Reviewer Review Type Date Requested Status
Jon Hill Pending
Fluidity Core Team Pending
Review via email: mp+92388@code.launchpad.net

This proposal has been superseded by a proposal from 2012-02-11.

Description of the change

Fix to bug lp:922025. This tidies up the manner in which the pressure initial condition is set from a free-surface height field provided in a netCDF file.

Summary of changes:
 - The special case, legacy method has been removed.
 - If the input format is not recognised, the code will abort with an error detailing the problematic field and the schema path of the invalid format.
 - The 'standard' format is now named 'raw' (instead of 'other'). This is the case where no post-processing is performed on the source data, and the field is initialised by the raw data present in the netCDF file.
 - Included logging messages to indicate which field is being populated and the source netCDF file (logging level 1).
 - Logging of the post-processing applied (logging level 3).
 - For the pressure boundary condition set from a free-surface field in particular, logging level 3 will report the min and max values of the field before and after the conversion.
 - Documentation in the schema detailing the available format options and the renaming described above.

There are currently no tests, examples or longtests that are affected by the above change, but possibly user-generated initialisation flml files that do use the legacy implementation of the pressure initial condition set from free-surface netCDF. In this case, the additional logging added with this change should make it easy to identify the change required to adopt the improved version of this import.

In short, the following example highlights the change necessary:

The option path:
  /material_phase::Ocean/scalar_field::Pressure/prognostic/initial_condition::WholeMesh/from_netcdf/format/Free-surface height

should become:
  /material_phase::Ocean/scalar_field::Pressure/prognostic/initial_condition::WholeMesh/free_surface/from_netcdf/format/raw

(where the file location is specified under the 'from_netcdf' node in each case).

To post a comment you must log in.
3912. By Adam Candy

A new section in the manual describing how to initialise the pressure field by specifying the free surface height.
Removal of the description of the legacy method to achieve this.
Other corrections to nearby sections.

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

The manual has been updated to reflect the changes made.

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

Looks good to me.

One minor typo in schemas/input_output.rnc
Data should be in the form x,y,z(y,x) where where x and y are the coordinates ->
Data should be in the form x,y,z(y,x) where x and y are the coordinates

Can we create a quick test of this functionality, including doctoring netcdf files to be invalid? How much effort would that be, do you think?

3913. By Adam Candy

Merge in of the trunk.

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

Thanks for taking a look Jon - the typo has been fixed. Also noticed a spelling mistake above too. These have all been in there for quite some time now!

I'm working on a test for the functionality - see:
https://code.launchpad.net/~fluidity-core/fluidity/netcdftests

The main test is in place, just looking at how to check invalid files.

I've also discovered a bug in the reader that will go up shortly...

3914. By Adam Candy

Correct the typo highlighted by Jon (thanks) and a spelling.

3915. By Adam Candy

Merge from trunk (to pick up improved netcdf error reporting changes).

3916. By Adam Candy

New test case: netcdf_read_free_surface
This creates a valid netCDF file containing a free surface height in the domain x,y in [-1.2,1.2]. This is read in by Fluidity as a free surface and applied as an initial condition on pressure. From this, Fluidity calculates the free surface as a diagnostic, which is provided in the outputted VTU file, alongside a field containing the analytic function used to create the netCDF file in the first place (here described in height.py). The test compares the difference between these two fields, which should be small, due to the interpolation of the netCDF file.

In summary this case tests:
  - NetCDF reader
  - Reading of a free surface and conversion into a pressure initial condition
  - Creation of the free surface diagnostic from the pressure field (including its extrapolation down from the top surface)
  - Creation of prescribed scalar fields from Python

3917. By Adam Candy

A new test case: netcdf_read_errors
This checks the errors reported when an attempt to read an invalid NetCDF file is made. Here 'invalid' refers to a file that is itself an invalid, non-conforming NetCDF file, or is of a format not supported by Fluidity.

Five types of NetCDF files are checked:
  - One which does not provide all the data requested,
  - One is missing a dimension (i.e. it provides only a 1d field),
  - One is missing the main variable,
  - One contains an incorrectly-labelled dimension (as 'lat', not 'x'), and
  - One has the variable incorrectly labelled (as 'height', not 'z').

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

Please take a look at the two new test cases added, 'netcdf_read_free_surface' and 'netcdf_read_errors'. Combined, these two test cases check the free surface initialisation discussed here and in bug lp:922025, and also the error reporting by the netCDF reader, tackled by bug lp:920944. They test:
  - NetCDF reader
  - Reading of a free surface and conversion into a pressure initial condition
  - Creation of the free surface diagnostic from the pressure field (including its extrapolation down from the top surface)
  - Creation of prescribed scalar fields from Python
and five types of invalid NetCDF files:
Five types of NetCDF files are checked:
  - One which does not provide all the data requested,
  - One is missing a dimension (i.e. it provides only a 1d field),
  - One is missing the main variable,
  - One contains an incorrectly-labelled dimension (as 'lat', not 'x'), and
  - One has the variable incorrectly labelled (as 'height', not 'z').

The NetCDF reader is now tested!

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

The above addresses Jon's suggestions, and I think it is fine to be merged and then released in 4.1.4.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'manual/configuring_fluidity.tex'
2--- manual/configuring_fluidity.tex 2011-11-23 11:03:53 +0000
3+++ manual/configuring_fluidity.tex 2012-02-11 17:18:19 +0000
4@@ -873,19 +873,31 @@
5
6 The initial state of certain fields can be set from external data contained within a NetCDF file.
7 This functionality can be used by selecting the \option{\ldots/initial\_condition/from\_netcdf/format}
8-option. This feature is currently intended for setting, for example, the initial free surface elevation
9-in a Tsunami simulation. This option will not currently work with multi-layered data files. Supported
10+option.
11+This option will not currently work with multi-layered data files. Supported
12 NetCDF file conventions include the NetCDF-CF 1.x convention.
13
14 \subsubsection{Setting fields from NEMO data}\label{sec:setting_from_nemo}
15 \index{field!from Nemo}
16 Initial conditions of prognostic fields and the values of prescribed fields can also be set from an external NEMO
17 data file. The external data file is in the NETCDF format and data is currently available for pressure, temperature, salinity
18-and velocity. To set the initial condition of a prognostic field from NEMO data, chose the option
19+and velocity. To set the initial condition of a prognostic field from NEMO data, choose the option
20 \option{\ldots/prognostic/initial\_condition/NEMO\_data} and then under \option{format} select the required data format. For scalar fields
21 the formats available are `Temperature', `Salinity' and `Free-surface height', for vector fields `Velocity' is the only available format.
22 Setting the value of prescribed fields from NEMO data works similarly. Set the option \option{\ldots/prescribed/value/NEMO\_data} and then proceed as above.
23
24+\subsubsection{Setting an initial free surface height}\label{sec:setting_free_surface_height}
25+\index{inital conditions!free surface height}
26+\index{free surface!initial condition}
27+The free surface height is contained within the Pressure field. To apply an initial condition on free surface height,
28+choose the \option{\ldots/free\_surface} under the relevant Pressure initial condition option.
29+With this option, it is possible to set the initial free surface elevation in a tsunami simulation, for example.
30+The initial condition can be applied using the approaches outlined above, in this section~\ref{sec:setting_field_values}.
31+It is recommended that a diagnostic Free Surface field is included if this option is used.
32+
33+If set from a NetCDF file using the option \option{\ldots/initial\_condition/from\_netcdf}, and the file provides exactly the
34+free surface height, it is important that the child option \option{\ldots/initial\_condition/from\_netcdf/format} is set to `raw'.
35+
36 \subsection{Region IDs}
37 \index{region ID}
38 If the input mesh defines a number of region IDs then these may be employed
39
40=== modified file 'ocean_forcing/load_netcdf.F90'
41--- ocean_forcing/load_netcdf.F90 2010-12-17 16:50:11 +0000
42+++ ocean_forcing/load_netcdf.F90 2012-02-11 17:18:19 +0000
43@@ -31,14 +31,20 @@
44 call get_option(trim(path)//"/from_netcdf/format", format)
45
46 select case (format)
47- ! This is currently the only 'special' case, but may change as people need to initialize
48- ! different fields
49- case ("Free-surface height")
50- call get_option("/physical_parameters/gravity/magnitude", gravity_magnitude, stat=stat)
51- if (stat/=0) then
52- FLAbort("Trying to initialize an initial condition for the free surface without a gravitational field")
53- endif
54- call scale(field, gravity_magnitude)
55+ ! It is possible to manipulate imported netCDF data here.
56+ ! Note that the 'Free-surface height' format option is no longer supported.
57+ ! In this case the 'free_surface' node under pressure initial conditions should be used.
58+
59+ case ("raw")
60+ ewrite(3,*) "The data used to initialise field " // trim(field%name) // &
61+ ", has been treated as the raw values and not post-processed after import."
62+
63+ case default
64+ ewrite(-1,*) "The format " // trim(format) // ", is not a recognised method to handle netCDF files."
65+ ewrite(-1,*) "Please specify a valid format for initialiasing the field " // trim(field%name) // &
66+ ", at " // trim(path) // "/from_netcdf/format"
67+ FLAbort("Fatal error initialising a field from a netCDF file.")
68+
69 end select
70
71 end subroutine
72@@ -51,14 +57,16 @@
73 real, dimension(position%dim,node_count(position)) :: temp_pos
74 character(len=FIELD_NAME_LEN) :: filename
75 real, dimension(:), allocatable :: X, Y, Z
76-
77 integer :: NNodes, i
78
79+ assert(node_count(field)==node_count(position))
80+
81 call get_option(trim(path)//"/from_netcdf/file_name", filename)
82
83- assert(node_count(field)==node_count(position))
84+ ewrite(1,*) "Populating field " // trim(field%name) // &
85+ ", with data from the netCDF file: " // trim(filename)
86
87- NNodes=node_count(field)
88+ NNodes = node_count(field)
89
90 allocate(X(NNodes), Y(NNodes), Z(NNodes))
91
92@@ -98,4 +106,4 @@
93
94 end subroutine
95
96-end module load_netcdf_module
97\ No newline at end of file
98+end module load_netcdf_module
99
100=== modified file 'preprocessor/Initialise_Fields.F90'
101--- preprocessor/Initialise_Fields.F90 2011-11-14 18:13:34 +0000
102+++ preprocessor/Initialise_Fields.F90 2012-02-11 17:18:19 +0000
103@@ -111,7 +111,9 @@
104 else if(have_option(trim(path)//"/free_surface")) then
105 call initialise_field(field, trim(path)//"/free_surface", position, time=time, phase_path=trim(phase_path))
106 ! Scale the entered freesurface height by the magnitude of gravity to give the pressure initial condition
107+ ewrite(3, *) "Free-surface to pressure minmax pre-conversion ", minval(field), maxval(field)
108 call convert_free_surface_to_pressure(field, phase_path)
109+ ewrite(3, *) "Free-surface to pressure minmax post-conversion ", minval(field), maxval(field)
110
111 else if(have_option(trim(path) // "/from_file")) then
112
113
114=== modified file 'schemas/input_output.rnc'
115--- schemas/input_output.rnc 2011-07-27 16:57:15 +0000
116+++ schemas/input_output.rnc 2012-02-11 17:18:19 +0000
117@@ -180,15 +180,18 @@
118 }
119 }|
120 ## Initialize a single field from data contained within a NetCDF file.
121- ## Data should be in the form x,y,z(y,x) where where x and y are the coordinates
122- ## (either cartesian or longitude-latitude) and z is the value of the intial
123+ ## Data should be in the form x, y, z(y,x) where x and y are the coordinates
124+ ## (either cartesian or longitude-latitude) and z is the value of the initial
125 ## condition to be imposed (or in the GEBCO, COARDS or CF-1.0 formats).
126 ## Note: This option currently only supports 'single layer' data sets.
127+ ##
128+ ## Current format options are: raw
129+ ## Simulations using the format 'other' should be updated to use 'raw'.
130 element from_netcdf {
131 attribute file_name { xsd:string },
132 element format {
133 element string_value {
134- "Free-surface height"|"other"
135+ "raw"
136 }
137 }
138 }|
139@@ -249,15 +252,18 @@
140 }
141 }|
142 ## Initialize a single field from data contained within a NetCDF file.
143- ## Data should be in the form x,y,z where where x and y are the coordinates
144- ## (either cartesian or longitude-latitude) and z is the value of the intial
145- ## condition to be imposed.
146+ ## Data should be in the form x, y, z(y,x) where x and y are the coordinates
147+ ## (either cartesian or longitude-latitude) and z is the value of the initial
148+ ## condition to be imposed (or in the GEBCO, COARDS or CF-1.0 formats).
149 ## Note: This option currently only supports 'single layer' data sets.
150+ ##
151+ ## Current format options are: raw
152+ ## Simulations using the format 'other' should be updated to use 'raw'.
153 element from_netcdf {
154 attribute file_name { xsd:string },
155 element format {
156 element string_value {
157- "Free-surface height"|"other"
158+ "raw"
159 }
160 }
161 }|
162
163=== modified file 'schemas/input_output.rng'
164--- schemas/input_output.rng 2011-07-27 16:57:15 +0000
165+++ schemas/input_output.rng 2012-02-11 17:18:19 +0000
166@@ -229,19 +229,19 @@
167 </element>
168 <element name="from_netcdf">
169 <a:documentation>Initialize a single field from data contained within a NetCDF file.
170-Data should be in the form x,y,z(y,x) where where x and y are the coordinates
171-(either cartesian or longitude-latitude) and z is the value of the intial
172+Data should be in the form x, y, z(y,x) where x and y are the coordinates
173+(either cartesian or longitude-latitude) and z is the value of the initial
174 condition to be imposed (or in the GEBCO, COARDS or CF-1.0 formats).
175-Note: This option currently only supports 'single layer' data sets.</a:documentation>
176+Note: This option currently only supports 'single layer' data sets.
177+
178+Current format options are: raw
179+Simulations using the format 'other' should be updated to use 'raw'.</a:documentation>
180 <attribute name="file_name">
181 <data type="string"/>
182 </attribute>
183 <element name="format">
184 <element name="string_value">
185- <choice>
186- <value>Free-surface height</value>
187- <value>other</value>
188- </choice>
189+ <value>raw</value>
190 </element>
191 </element>
192 </element>
193@@ -309,19 +309,19 @@
194 </element>
195 <element name="from_netcdf">
196 <a:documentation>Initialize a single field from data contained within a NetCDF file.
197-Data should be in the form x,y,z where where x and y are the coordinates
198-(either cartesian or longitude-latitude) and z is the value of the intial
199-condition to be imposed.
200-Note: This option currently only supports 'single layer' data sets.</a:documentation>
201+Data should be in the form x, y, z(y,x) where x and y are the coordinates
202+(either cartesian or longitude-latitude) and z is the value of the initial
203+condition to be imposed (or in the GEBCO, COARDS or CF-1.0 formats).
204+Note: This option currently only supports 'single layer' data sets.
205+
206+Current format options are: raw
207+Simulations using the format 'other' should be updated to use 'raw'.</a:documentation>
208 <attribute name="file_name">
209 <data type="string"/>
210 </attribute>
211 <element name="format">
212 <element name="string_value">
213- <choice>
214- <value>Free-surface height</value>
215- <value>other</value>
216- </choice>
217+ <value>raw</value>
218 </element>
219 </element>
220 </element>
221
222=== added directory 'tests/netcdf_read_errors'
223=== added file 'tests/netcdf_read_errors/Makefile'
224--- tests/netcdf_read_errors/Makefile 1970-01-01 00:00:00 +0000
225+++ tests/netcdf_read_errors/Makefile 2012-02-11 17:18:19 +0000
226@@ -0,0 +1,18 @@
227+
228+default: run
229+
230+run: input
231+ ../../bin/fluidity -v 3 -l missingdata.flml
232+
233+%.flml: valid.flml
234+ @sed -e 's/valid\.nc/$*.nc/' $^ > $@
235+
236+input: clean
237+ ./createnetcdf.py
238+ $(MAKE) missingdata.flml missingdimension.flml missingvariable.flml incorrectdimension.flml incorrectvariable.flml
239+ ../../bin/create_aligned_mesh mesh 2.0 2.0 1.0 10 10 1 -- -1.0 -1.0 -1.0
240+
241+clean:
242+ rm -f *.{nc,pyc,ele,node,face,vtu,stat,s,err} matrixdump* fluidity.*
243+ rm -f missing{data,dimension,variable}.flml incorrect{dimension,variable}.flml
244+
245
246=== added file 'tests/netcdf_read_errors/createnetcdf.py'
247--- tests/netcdf_read_errors/createnetcdf.py 1970-01-01 00:00:00 +0000
248+++ tests/netcdf_read_errors/createnetcdf.py 2012-02-11 17:18:19 +0000
249@@ -0,0 +1,86 @@
250+#!/usr/bin/env python
251+
252+from Scientific.IO.NetCDF import NetCDFFile
253+from numpy import arange, zeros
254+
255+def create(missingdata = False, missingdimension = False, missingvariable = False, incorrectdimension = False, incorrectvariable = False):
256+
257+ if (missingdata):
258+ filename = 'missingdata.nc'
259+ description = ', with missing data.'
260+ elif (missingdimension):
261+ filename = 'missingdimension.nc'
262+ description = ', with a missing dimension.'
263+ elif (missingvariable):
264+ filename = 'missingvariable.nc'
265+ description = ', with a missing variable.'
266+ elif (incorrectdimension):
267+ filename = 'incorrectdimension.nc'
268+ description = ', with an incorrect dimension label.'
269+ elif (incorrectvariable):
270+ filename = 'incorrectvariable.nc'
271+ description = ', with an incorrect variable label.'
272+ else:
273+ filename = 'valid.nc'
274+ description = '.'
275+
276+ print "Creating " + filename + description
277+
278+ f = NetCDFFile(filename, 'w')
279+ f.description = 'Example free surface height' + description
280+
281+ if (missingdata):
282+ offset = -0.4
283+ else:
284+ offset = 0.0
285+
286+ x = arange(-1.2 + offset, 1.21 + offset, 0.2)
287+ y = arange(-1.2, 1.21, 0.2)
288+ h = zeros((len(x),len(y)))
289+
290+ for i in range(len(x)):
291+ for j in range(len(y)):
292+ # Nice ordering netCDF API - y,x !
293+ h[j,i] = x[i] * y[j]
294+
295+ if (not incorrectdimension):
296+ xdimlabel = 'x'
297+ else:
298+ xdimlabel = 'lat'
299+ ydimlabel = 'y'
300+ if (not incorrectvariable):
301+ zdimlabel = 'z'
302+ else:
303+ zdimlabel = 'height'
304+
305+ print xdimlabel, ydimlabel, zdimlabel
306+
307+ # dimensions
308+ f.createDimension(xdimlabel, len(x))
309+ if (not missingdimension):
310+ f.createDimension(ydimlabel, len(y))
311+
312+ # variables
313+ fx = f.createVariable(xdimlabel, 'd', (xdimlabel,))
314+ fx[:] = x
315+ if (not missingdimension):
316+ fy = f.createVariable(ydimlabel, 'd', (ydimlabel,))
317+ fy[:] = y
318+ if (not missingvariable):
319+ fh = f.createVariable(zdimlabel, 'd', (xdimlabel, ydimlabel,))
320+ fh[:] = h
321+ else:
322+ fh = f.createVariable(zdimlabel, 'd', (xdimlabel,))
323+ fh[:] = x
324+
325+ f.close()
326+
327+create()
328+create(missingdata=True)
329+create(missingdimension=True)
330+create(missingvariable=True)
331+create(incorrectdimension=True)
332+create(incorrectvariable=True)
333+
334+
335+
336
337=== added file 'tests/netcdf_read_errors/missingdata.err.sample'
338--- tests/netcdf_read_errors/missingdata.err.sample 1970-01-01 00:00:00 +0000
339+++ tests/netcdf_read_errors/missingdata.err.sample 2012-02-11 17:18:19 +0000
340@@ -0,0 +1,44 @@
341+Point [0.8, -1] not found in netCDF file, missingdata.nc.
342+Point [1, -1] not found in netCDF file, missingdata.nc.
343+Point [0.8, -0.8] not found in netCDF file, missingdata.nc.
344+Point [1, -0.8] not found in netCDF file, missingdata.nc.
345+Point [0.8, -0.6] not found in netCDF file, missingdata.nc.
346+Point [1, -0.6] not found in netCDF file, missingdata.nc.
347+Point [0.8, -0.4] not found in netCDF file, missingdata.nc.
348+Point [1, -0.4] not found in netCDF file, missingdata.nc.
349+Point [0.8, -0.2] not found in netCDF file, missingdata.nc.
350+Point [1, -0.2] not found in netCDF file, missingdata.nc.
351+Point [0.8, 0] not found in netCDF file, missingdata.nc.
352+Point [1, 0] not found in netCDF file, missingdata.nc.
353+Point [0.8, 0.2] not found in netCDF file, missingdata.nc.
354+Point [1, 0.2] not found in netCDF file, missingdata.nc.
355+Point [0.8, 0.4] not found in netCDF file, missingdata.nc.
356+Point [1, 0.4] not found in netCDF file, missingdata.nc.
357+Point [0.8, 0.6] not found in netCDF file, missingdata.nc.
358+Point [1, 0.6] not found in netCDF file, missingdata.nc.
359+Point [0.8, 0.8] not found in netCDF file, missingdata.nc.
360+Point [1, 0.8] not found in netCDF file, missingdata.nc.
361+Point [0.8, 1] not found in netCDF file, missingdata.nc.
362+Point [1, 1] not found in netCDF file, missingdata.nc.
363+Point [0.8, -1] not found in netCDF file, missingdata.nc.
364+Point [1, -1] not found in netCDF file, missingdata.nc.
365+Point [0.8, -0.8] not found in netCDF file, missingdata.nc.
366+Point [1, -0.8] not found in netCDF file, missingdata.nc.
367+Point [0.8, -0.6] not found in netCDF file, missingdata.nc.
368+Point [1, -0.6] not found in netCDF file, missingdata.nc.
369+Point [0.8, -0.4] not found in netCDF file, missingdata.nc.
370+Point [1, -0.4] not found in netCDF file, missingdata.nc.
371+Point [0.8, -0.2] not found in netCDF file, missingdata.nc.
372+Point [1, -0.2] not found in netCDF file, missingdata.nc.
373+Point [0.8, 0] not found in netCDF file, missingdata.nc.
374+Point [1, 0] not found in netCDF file, missingdata.nc.
375+Point [0.8, 0.2] not found in netCDF file, missingdata.nc.
376+Point [1, 0.2] not found in netCDF file, missingdata.nc.
377+Point [0.8, 0.4] not found in netCDF file, missingdata.nc.
378+Point [1, 0.4] not found in netCDF file, missingdata.nc.
379+Point [0.8, 0.6] not found in netCDF file, missingdata.nc.
380+Point [1, 0.6] not found in netCDF file, missingdata.nc.
381+Point [0.8, 0.8] not found in netCDF file, missingdata.nc.
382+Point [1, 0.8] not found in netCDF file, missingdata.nc.
383+Point [0.8, 1] not found in netCDF file, missingdata.nc.
384+Point [1, 1] not found in netCDF file, missingdata.nc.
385
386=== added file 'tests/netcdf_read_errors/netcdf_read_errors.xml'
387--- tests/netcdf_read_errors/netcdf_read_errors.xml 1970-01-01 00:00:00 +0000
388+++ tests/netcdf_read_errors/netcdf_read_errors.xml 2012-02-11 17:18:19 +0000
389@@ -0,0 +1,130 @@
390+<?xml version="1.0" encoding="UTF-8" ?>
391+<testproblem>
392+ <name>netcdf_read_errors</name>
393+ <owner userid="asc"/>
394+ <tags>flml netcdf</tags>
395+ <problem_definition length="medium" nprocs="1">
396+ <command_line>for name in valid missing{data,dimension,variable} incorrect{dimension,variable}; do echo "Running case ${name}"; ../../bin/fluidity "${name}.flml" 1>/dev/null 2>"${name}.err"; done</command_line>
397+ </problem_definition>
398+ <variables>
399+ <variable name="valid_err_filesize" language="python">
400+import os
401+valid_err_filesize = os.stat('valid.err').st_size
402+ </variable>
403+ <variable name="missingdata_err_linenumber" language="python">
404+def filelines(filename):
405+ with open(filename) as f:
406+ for i, l in enumerate(f):
407+ pass
408+ return i + 1
409+missingdata_err_linenumber = filelines('missingdata.err')
410+ </variable>
411+ <variable name="missingdimension_err_linenumber" language="python">
412+def filelines(filename):
413+ with open(filename) as f:
414+ for i, l in enumerate(f):
415+ pass
416+ return i + 1
417+missingdimension_err_linenumber = filelines('missingdimension.err')
418+ </variable>
419+ <variable name="missingvariable_err_linenumber" language="python">
420+def filelines(filename):
421+ with open(filename) as f:
422+ for i, l in enumerate(f):
423+ pass
424+ return i + 1
425+missingvariable_err_linenumber = filelines('missingvariable.err')
426+ </variable>
427+ <variable name="incorrectdimension_err_linenumber" language="python">
428+def filelines(filename):
429+ with open(filename) as f:
430+ for i, l in enumerate(f):
431+ pass
432+ return i + 1
433+incorrectdimension_err_linenumber = filelines('incorrectdimension.err')
434+ </variable>
435+ <variable name="incorrectvariable_err_linenumber" language="python">
436+def filelines(filename):
437+ with open(filename) as f:
438+ for i, l in enumerate(f):
439+ pass
440+ return i + 1
441+incorrectvariable_err_linenumber = filelines('incorrectvariable.err')
442+ </variable>
443+ <variable name="missingdata_err" language="python">
444+fileHandle = open('missingdata.err.sample')
445+correct = fileHandle.read()
446+fileHandle.close()
447+fileHandle = open('missingdata.err')
448+line = fileHandle.read()
449+fileHandle.close()
450+missingdata_err = ( line == correct )
451+ </variable>
452+ <variable name="missingdimension_err" language="python">
453+correct = 'ncdimid: ncid 65536: NetCDF: Invalid dimension ID or name\n'
454+fileHandle = open('missingdimension.err')
455+line = fileHandle.read()
456+fileHandle.close()
457+missingdimension_err = ( line == correct )
458+ </variable>
459+ <variable name="missingvariable_err" language="python">
460+correct = 'ncvarid: ncid 65536: NetCDF: Variable not found\n'
461+fileHandle = open('missingvariable.err')
462+line = fileHandle.read()
463+fileHandle.close()
464+missingvariable_err = ( line == correct )
465+ </variable>
466+ <variable name="incorrectdimension_err" language="python">
467+correct = 'ncdimid: ncid 65536: NetCDF: Invalid dimension ID or name\n'
468+fileHandle = open('incorrectdimension.err')
469+line = fileHandle.read()
470+fileHandle.close()
471+incorrectdimension_err = ( line == correct )
472+ </variable>
473+ <variable name="incorrectvariable_err" language="python">
474+correct = 'ncvarid: ncid 65536: NetCDF: Variable not found\n'
475+fileHandle = open('incorrectvariable.err')
476+line = fileHandle.read()
477+fileHandle.close()
478+incorrectvariable_err = ( line == correct )
479+ </variable>
480+ </variables>
481+ <pass_tests>
482+ <test name="Checking the valid case has reported no errors" language="python">
483+assert ( valid_err_filesize == 0 )
484+ </test>
485+ <test name="Checking the case with missing data has reported exactly 44 errors" language="python">
486+assert ( missingdata_err_linenumber == 44 )
487+ </test>
488+ <test name="Checking the case with a missing dimension has reported exactly 1 error" language="python">
489+assert ( missingdimension_err_linenumber == 1 )
490+ </test>
491+ <test name="Checking the case with a missing variable has reported exactly 1 error" language="python">
492+assert ( missingvariable_err_linenumber == 1 )
493+ </test>
494+ <test name="Checking the case with an incorrect dimension label has reported exactly 1 error" language="python">
495+assert ( incorrectdimension_err_linenumber == 1 )
496+ </test>
497+ <test name="Checking the case with an incorrect variable label has reported exactly 1 error" language="python">
498+assert ( incorrectvariable_err_linenumber == 1 )
499+ </test>
500+ <test name="Checking the case with missing data has reported the correct errors" language="python">
501+assert ( missingdata_err )
502+ </test>
503+ <test name="Checking the case with a missing dimension has reported the correct error" language="python">
504+assert ( missingdimension_err )
505+ </test>
506+ <test name="Checking the case with a missing variable has reported the correct error" language="python">
507+assert ( missingvariable_err )
508+ </test>
509+ <test name="Checking the case with an incorrect dimension label has reported the correct error" language="python">
510+assert ( incorrectdimension_err )
511+ </test>
512+ <test name="Checking the case with an incorrect variable label has reported the correct error" language="python">
513+assert ( incorrectvariable_err )
514+ </test>
515+ </pass_tests>
516+ <warn_tests>
517+ </warn_tests>
518+</testproblem>
519+
520
521=== added file 'tests/netcdf_read_errors/valid.flml'
522--- tests/netcdf_read_errors/valid.flml 1970-01-01 00:00:00 +0000
523+++ tests/netcdf_read_errors/valid.flml 2012-02-11 17:18:19 +0000
524@@ -0,0 +1,292 @@
525+<?xml version='1.0' encoding='utf-8'?>
526+<fluidity_options>
527+ <simulation_name>
528+ <string_value lines="1">netcdf_read_free_surface</string_value>
529+ </simulation_name>
530+ <problem_type>
531+ <string_value lines="1">fluids</string_value>
532+ </problem_type>
533+ <geometry>
534+ <dimension>
535+ <integer_value rank="0">3</integer_value>
536+ </dimension>
537+ <mesh name="CoordinateMesh">
538+ <from_file file_name="mesh">
539+ <format name="triangle"/>
540+ <stat>
541+ <include_in_stat/>
542+ </stat>
543+ </from_file>
544+ </mesh>
545+ <mesh name="VelocityMesh">
546+ <from_mesh>
547+ <mesh name="CoordinateMesh"/>
548+ <stat>
549+ <exclude_from_stat/>
550+ </stat>
551+ </from_mesh>
552+ </mesh>
553+ <mesh name="PressureMesh">
554+ <from_mesh>
555+ <mesh name="CoordinateMesh"/>
556+ <stat>
557+ <exclude_from_stat/>
558+ </stat>
559+ </from_mesh>
560+ </mesh>
561+ <quadrature>
562+ <degree>
563+ <integer_value rank="0">2</integer_value>
564+ </degree>
565+ </quadrature>
566+ <ocean_boundaries>
567+ <top_surface_ids>
568+ <integer_value shape="1" rank="1">2</integer_value>
569+ </top_surface_ids>
570+ <bottom_surface_ids>
571+ <integer_value shape="1" rank="1">1</integer_value>
572+ </bottom_surface_ids>
573+ <scalar_field name="DistanceToTop" rank="0">
574+ <diagnostic>
575+ <algorithm name="Internal" material_phase_support="multiple"/>
576+ <mesh name="CoordinateMesh"/>
577+ <output/>
578+ <stat/>
579+ <convergence>
580+ <include_in_convergence/>
581+ </convergence>
582+ <detectors>
583+ <include_in_detectors/>
584+ </detectors>
585+ <steady_state>
586+ <include_in_steady_state/>
587+ </steady_state>
588+ </diagnostic>
589+ </scalar_field>
590+ <scalar_field name="DistanceToBottom" rank="0">
591+ <diagnostic>
592+ <algorithm name="Internal" material_phase_support="multiple"/>
593+ <mesh name="CoordinateMesh"/>
594+ <output/>
595+ <stat/>
596+ <convergence>
597+ <include_in_convergence/>
598+ </convergence>
599+ <detectors>
600+ <include_in_detectors/>
601+ </detectors>
602+ <steady_state>
603+ <include_in_steady_state/>
604+ </steady_state>
605+ </diagnostic>
606+ </scalar_field>
607+ </ocean_boundaries>
608+ </geometry>
609+ <io>
610+ <dump_format>
611+ <string_value>vtk</string_value>
612+ </dump_format>
613+ <dump_period>
614+ <constant>
615+ <real_value rank="0">1.0</real_value>
616+ </constant>
617+ </dump_period>
618+ <output_mesh name="VelocityMesh"/>
619+ <stat/>
620+ </io>
621+ <timestepping>
622+ <current_time>
623+ <real_value rank="0">2.0</real_value>
624+ </current_time>
625+ <timestep>
626+ <real_value rank="0">1.0</real_value>
627+ </timestep>
628+ <finish_time>
629+ <real_value rank="0">1.0</real_value>
630+ </finish_time>
631+ </timestepping>
632+ <physical_parameters>
633+ <gravity>
634+ <magnitude>
635+ <real_value rank="0">9.81</real_value>
636+ </magnitude>
637+ <vector_field name="GravityDirection" rank="1">
638+ <prescribed>
639+ <mesh name="CoordinateMesh"/>
640+ <value name="WholeMesh">
641+ <constant>
642+ <real_value shape="3" dim1="dim" rank="1">0.0 0.0 -1.0</real_value>
643+ </constant>
644+ </value>
645+ <output/>
646+ <stat>
647+ <include_in_stat/>
648+ </stat>
649+ <detectors>
650+ <exclude_from_detectors/>
651+ </detectors>
652+ </prescribed>
653+ </vector_field>
654+ </gravity>
655+ </physical_parameters>
656+ <material_phase name="fluid">
657+ <equation_of_state>
658+ <fluids>
659+ <linear>
660+ <reference_density>
661+ <real_value rank="0">1.0</real_value>
662+ </reference_density>
663+ <subtract_out_hydrostatic_level/>
664+ </linear>
665+ </fluids>
666+ </equation_of_state>
667+ <scalar_field name="Pressure" rank="0">
668+ <prognostic>
669+ <mesh name="PressureMesh"/>
670+ <spatial_discretisation>
671+ <continuous_galerkin>
672+ <integrate_continuity_by_parts/>
673+ </continuous_galerkin>
674+ </spatial_discretisation>
675+ <scheme>
676+ <poisson_pressure_solution>
677+ <string_value lines="1">never</string_value>
678+ </poisson_pressure_solution>
679+ <use_projection_method/>
680+ </scheme>
681+ <solver>
682+ <iterative_method name="cg"/>
683+ <preconditioner name="sor"/>
684+ <relative_error>
685+ <real_value rank="0">1.0e-7</real_value>
686+ </relative_error>
687+ <max_iterations>
688+ <integer_value rank="0">10</integer_value>
689+ </max_iterations>
690+ <never_ignore_solver_failures/>
691+ <diagnostics>
692+ <monitors/>
693+ </diagnostics>
694+ </solver>
695+ <initial_condition name="WholeMesh">
696+ <free_surface>
697+ <from_netcdf file_name="valid.nc">
698+ <format>
699+ <string_value>raw</string_value>
700+ </format>
701+ </from_netcdf>
702+ </free_surface>
703+ </initial_condition>
704+ <output/>
705+ <stat/>
706+ <convergence>
707+ <include_in_convergence/>
708+ </convergence>
709+ <detectors>
710+ <exclude_from_detectors/>
711+ </detectors>
712+ <steady_state>
713+ <include_in_steady_state/>
714+ </steady_state>
715+ <no_interpolation/>
716+ </prognostic>
717+ </scalar_field>
718+ <vector_field name="Velocity" rank="1">
719+ <prognostic>
720+ <mesh name="VelocityMesh"/>
721+ <equation name="LinearMomentum"/>
722+ <spatial_discretisation>
723+ <continuous_galerkin>
724+ <stabilisation>
725+ <no_stabilisation/>
726+ </stabilisation>
727+ <mass_terms>
728+ <lump_mass_matrix/>
729+ </mass_terms>
730+ <advection_terms/>
731+ <stress_terms>
732+ <tensor_form/>
733+ </stress_terms>
734+ </continuous_galerkin>
735+ <conservative_advection>
736+ <real_value rank="0">1.0</real_value>
737+ </conservative_advection>
738+ </spatial_discretisation>
739+ <temporal_discretisation>
740+ <theta>
741+ <real_value rank="0">0.5</real_value>
742+ </theta>
743+ <relaxation>
744+ <real_value rank="0">0</real_value>
745+ </relaxation>
746+ </temporal_discretisation>
747+ <solver>
748+ <iterative_method name="gmres">
749+ <restart>
750+ <integer_value rank="0">30</integer_value>
751+ </restart>
752+ </iterative_method>
753+ <preconditioner name="sor"/>
754+ <relative_error>
755+ <real_value rank="0">1.0E-7</real_value>
756+ </relative_error>
757+ <max_iterations>
758+ <integer_value rank="0">10</integer_value>
759+ </max_iterations>
760+ <never_ignore_solver_failures/>
761+ <diagnostics>
762+ <monitors/>
763+ </diagnostics>
764+ </solver>
765+ <initial_condition name="WholeMesh">
766+ <constant>
767+ <real_value shape="3" dim1="dim" rank="1">0.0 0.0 0.0</real_value>
768+ </constant>
769+ </initial_condition>
770+ <boundary_conditions name="top">
771+ <surface_ids>
772+ <integer_value shape="1" rank="1">2</integer_value>
773+ </surface_ids>
774+ <type name="free_surface"/>
775+ </boundary_conditions>
776+ <output/>
777+ <stat>
778+ <include_in_stat/>
779+ <previous_time_step>
780+ <exclude_from_stat/>
781+ </previous_time_step>
782+ <nonlinear_field>
783+ <exclude_from_stat/>
784+ </nonlinear_field>
785+ </stat>
786+ <convergence>
787+ <include_in_convergence/>
788+ </convergence>
789+ <detectors>
790+ <include_in_detectors/>
791+ </detectors>
792+ <steady_state>
793+ <include_in_steady_state/>
794+ </steady_state>
795+ <consistent_interpolation/>
796+ </prognostic>
797+ </vector_field>
798+ <scalar_field name="FreeSurface" rank="0">
799+ <diagnostic>
800+ <algorithm name="Internal" material_phase_support="multiple"/>
801+ <mesh name="PressureMesh"/>
802+ <output/>
803+ <stat/>
804+ <convergence>
805+ <include_in_convergence/>
806+ </convergence>
807+ <detectors>
808+ <include_in_detectors/>
809+ </detectors>
810+ <steady_state>
811+ <include_in_steady_state/>
812+ </steady_state>
813+ </diagnostic>
814+ </scalar_field>
815+ </material_phase>
816+</fluidity_options>
817
818=== added directory 'tests/netcdf_read_free_surface'
819=== added file 'tests/netcdf_read_free_surface/Makefile'
820--- tests/netcdf_read_free_surface/Makefile 1970-01-01 00:00:00 +0000
821+++ tests/netcdf_read_free_surface/Makefile 2012-02-11 17:18:19 +0000
822@@ -0,0 +1,13 @@
823+
824+default: run
825+
826+run: input
827+ ../../bin/fluidity -v 3 -l netcdf_read_free_surface.flml
828+
829+input: clean
830+ ./createnetcdf.py
831+ ../../bin/create_aligned_mesh mesh 2.0 2.0 1.0 10 10 1 -- -1.0 -1.0 -1.0
832+
833+clean:
834+ rm -f height.nc *.pyc *.ele *.node *.face *.vtu *.stat *.s matrixdump* fluidity.*
835+
836
837=== added file 'tests/netcdf_read_free_surface/createnetcdf.py'
838--- tests/netcdf_read_free_surface/createnetcdf.py 1970-01-01 00:00:00 +0000
839+++ tests/netcdf_read_free_surface/createnetcdf.py 2012-02-11 17:18:19 +0000
840@@ -0,0 +1,33 @@
841+#!/usr/bin/env python
842+
843+from Scientific.IO.NetCDF import NetCDFFile
844+from numpy import arange, zeros
845+import height
846+
847+f = NetCDFFile('height.nc', 'w')
848+f.description = 'Example free surface height.'
849+
850+x = arange(-1.2, 1.21, 0.2)
851+y = arange(-1.2, 1.21, 0.2)
852+h = zeros((len(x),len(y)))
853+
854+for i in range(len(x)):
855+ for j in range(len(y)):
856+ # Nice ordering netCDF API - y,x !
857+ h[j,i] = height.function([x[i], y[j]])
858+
859+# dimensions
860+f.createDimension('x', len(x))
861+f.createDimension('y', len(y))
862+
863+# variables
864+fx = f.createVariable('x', 'd', ('x',))
865+fy = f.createVariable('y', 'd', ('y',))
866+fh = f.createVariable('z', 'd', ('x', 'y',))
867+
868+fx[:] = x
869+fy[:] = y
870+fh[:] = h
871+
872+f.close()
873+
874
875=== added file 'tests/netcdf_read_free_surface/height.py'
876--- tests/netcdf_read_free_surface/height.py 1970-01-01 00:00:00 +0000
877+++ tests/netcdf_read_free_surface/height.py 2012-02-11 17:18:19 +0000
878@@ -0,0 +1,13 @@
879+#!/usr/bin/env python
880+
881+from matplotlib.mlab import bivariate_normal
882+
883+def function(position):
884+ xg = 3.0 * position[0]
885+ yg = 3.0 * position[1]
886+ h1 = bivariate_normal(xg, yg, 1.0, 1.0, 0.0, 0.0)
887+ h2 = bivariate_normal(xg, yg, 1.5, 0.5, 1, 1)
888+ h = 10.0 * (h1 - h2)
889+ return h
890+
891+
892
893=== added file 'tests/netcdf_read_free_surface/netcdf_read_free_surface.flml'
894--- tests/netcdf_read_free_surface/netcdf_read_free_surface.flml 1970-01-01 00:00:00 +0000
895+++ tests/netcdf_read_free_surface/netcdf_read_free_surface.flml 2012-02-11 17:18:19 +0000
896@@ -0,0 +1,309 @@
897+<?xml version='1.0' encoding='utf-8'?>
898+<fluidity_options>
899+ <simulation_name>
900+ <string_value lines="1">netcdf_read_free_surface</string_value>
901+ </simulation_name>
902+ <problem_type>
903+ <string_value lines="1">fluids</string_value>
904+ </problem_type>
905+ <geometry>
906+ <dimension>
907+ <integer_value rank="0">3</integer_value>
908+ </dimension>
909+ <mesh name="CoordinateMesh">
910+ <from_file file_name="mesh">
911+ <format name="triangle"/>
912+ <stat>
913+ <include_in_stat/>
914+ </stat>
915+ </from_file>
916+ </mesh>
917+ <mesh name="VelocityMesh">
918+ <from_mesh>
919+ <mesh name="CoordinateMesh"/>
920+ <stat>
921+ <exclude_from_stat/>
922+ </stat>
923+ </from_mesh>
924+ </mesh>
925+ <mesh name="PressureMesh">
926+ <from_mesh>
927+ <mesh name="CoordinateMesh"/>
928+ <stat>
929+ <exclude_from_stat/>
930+ </stat>
931+ </from_mesh>
932+ </mesh>
933+ <quadrature>
934+ <degree>
935+ <integer_value rank="0">2</integer_value>
936+ </degree>
937+ </quadrature>
938+ <ocean_boundaries>
939+ <top_surface_ids>
940+ <integer_value shape="1" rank="1">2</integer_value>
941+ </top_surface_ids>
942+ <bottom_surface_ids>
943+ <integer_value shape="1" rank="1">1</integer_value>
944+ </bottom_surface_ids>
945+ <scalar_field name="DistanceToTop" rank="0">
946+ <diagnostic>
947+ <algorithm name="Internal" material_phase_support="multiple"/>
948+ <mesh name="CoordinateMesh"/>
949+ <output/>
950+ <stat/>
951+ <convergence>
952+ <include_in_convergence/>
953+ </convergence>
954+ <detectors>
955+ <include_in_detectors/>
956+ </detectors>
957+ <steady_state>
958+ <include_in_steady_state/>
959+ </steady_state>
960+ </diagnostic>
961+ </scalar_field>
962+ <scalar_field name="DistanceToBottom" rank="0">
963+ <diagnostic>
964+ <algorithm name="Internal" material_phase_support="multiple"/>
965+ <mesh name="CoordinateMesh"/>
966+ <output/>
967+ <stat/>
968+ <convergence>
969+ <include_in_convergence/>
970+ </convergence>
971+ <detectors>
972+ <include_in_detectors/>
973+ </detectors>
974+ <steady_state>
975+ <include_in_steady_state/>
976+ </steady_state>
977+ </diagnostic>
978+ </scalar_field>
979+ </ocean_boundaries>
980+ </geometry>
981+ <io>
982+ <dump_format>
983+ <string_value>vtk</string_value>
984+ </dump_format>
985+ <dump_period>
986+ <constant>
987+ <real_value rank="0">1.0</real_value>
988+ </constant>
989+ </dump_period>
990+ <output_mesh name="VelocityMesh"/>
991+ <stat/>
992+ </io>
993+ <timestepping>
994+ <current_time>
995+ <real_value rank="0">2.0</real_value>
996+ </current_time>
997+ <timestep>
998+ <real_value rank="0">1.0</real_value>
999+ </timestep>
1000+ <finish_time>
1001+ <real_value rank="0">1.0</real_value>
1002+ </finish_time>
1003+ </timestepping>
1004+ <physical_parameters>
1005+ <gravity>
1006+ <magnitude>
1007+ <real_value rank="0">9.81</real_value>
1008+ </magnitude>
1009+ <vector_field name="GravityDirection" rank="1">
1010+ <prescribed>
1011+ <mesh name="CoordinateMesh"/>
1012+ <value name="WholeMesh">
1013+ <constant>
1014+ <real_value shape="3" dim1="dim" rank="1">0.0 0.0 -1.0</real_value>
1015+ </constant>
1016+ </value>
1017+ <output/>
1018+ <stat>
1019+ <include_in_stat/>
1020+ </stat>
1021+ <detectors>
1022+ <exclude_from_detectors/>
1023+ </detectors>
1024+ </prescribed>
1025+ </vector_field>
1026+ </gravity>
1027+ </physical_parameters>
1028+ <material_phase name="fluid">
1029+ <equation_of_state>
1030+ <fluids>
1031+ <linear>
1032+ <reference_density>
1033+ <real_value rank="0">1.0</real_value>
1034+ </reference_density>
1035+ <subtract_out_hydrostatic_level/>
1036+ </linear>
1037+ </fluids>
1038+ </equation_of_state>
1039+ <scalar_field name="Pressure" rank="0">
1040+ <prognostic>
1041+ <mesh name="PressureMesh"/>
1042+ <spatial_discretisation>
1043+ <continuous_galerkin>
1044+ <integrate_continuity_by_parts/>
1045+ </continuous_galerkin>
1046+ </spatial_discretisation>
1047+ <scheme>
1048+ <poisson_pressure_solution>
1049+ <string_value lines="1">never</string_value>
1050+ </poisson_pressure_solution>
1051+ <use_projection_method/>
1052+ </scheme>
1053+ <solver>
1054+ <iterative_method name="cg"/>
1055+ <preconditioner name="sor"/>
1056+ <relative_error>
1057+ <real_value rank="0">1.0e-7</real_value>
1058+ </relative_error>
1059+ <max_iterations>
1060+ <integer_value rank="0">10</integer_value>
1061+ </max_iterations>
1062+ <never_ignore_solver_failures/>
1063+ <diagnostics>
1064+ <monitors/>
1065+ </diagnostics>
1066+ </solver>
1067+ <initial_condition name="WholeMesh">
1068+ <free_surface>
1069+ <from_netcdf file_name="height.nc">
1070+ <format>
1071+ <string_value>raw</string_value>
1072+ </format>
1073+ </from_netcdf>
1074+ </free_surface>
1075+ </initial_condition>
1076+ <output/>
1077+ <stat/>
1078+ <convergence>
1079+ <include_in_convergence/>
1080+ </convergence>
1081+ <detectors>
1082+ <exclude_from_detectors/>
1083+ </detectors>
1084+ <steady_state>
1085+ <include_in_steady_state/>
1086+ </steady_state>
1087+ <no_interpolation/>
1088+ </prognostic>
1089+ </scalar_field>
1090+ <vector_field name="Velocity" rank="1">
1091+ <prognostic>
1092+ <mesh name="VelocityMesh"/>
1093+ <equation name="LinearMomentum"/>
1094+ <spatial_discretisation>
1095+ <continuous_galerkin>
1096+ <stabilisation>
1097+ <no_stabilisation/>
1098+ </stabilisation>
1099+ <mass_terms>
1100+ <lump_mass_matrix/>
1101+ </mass_terms>
1102+ <advection_terms/>
1103+ <stress_terms>
1104+ <tensor_form/>
1105+ </stress_terms>
1106+ </continuous_galerkin>
1107+ <conservative_advection>
1108+ <real_value rank="0">1.0</real_value>
1109+ </conservative_advection>
1110+ </spatial_discretisation>
1111+ <temporal_discretisation>
1112+ <theta>
1113+ <real_value rank="0">0.5</real_value>
1114+ </theta>
1115+ <relaxation>
1116+ <real_value rank="0">0</real_value>
1117+ </relaxation>
1118+ </temporal_discretisation>
1119+ <solver>
1120+ <iterative_method name="gmres">
1121+ <restart>
1122+ <integer_value rank="0">30</integer_value>
1123+ </restart>
1124+ </iterative_method>
1125+ <preconditioner name="sor"/>
1126+ <relative_error>
1127+ <real_value rank="0">1.0E-7</real_value>
1128+ </relative_error>
1129+ <max_iterations>
1130+ <integer_value rank="0">10</integer_value>
1131+ </max_iterations>
1132+ <never_ignore_solver_failures/>
1133+ <diagnostics>
1134+ <monitors/>
1135+ </diagnostics>
1136+ </solver>
1137+ <initial_condition name="WholeMesh">
1138+ <constant>
1139+ <real_value shape="3" dim1="dim" rank="1">0.0 0.0 0.0</real_value>
1140+ </constant>
1141+ </initial_condition>
1142+ <boundary_conditions name="top">
1143+ <surface_ids>
1144+ <integer_value shape="1" rank="1">2</integer_value>
1145+ </surface_ids>
1146+ <type name="free_surface"/>
1147+ </boundary_conditions>
1148+ <output/>
1149+ <stat>
1150+ <include_in_stat/>
1151+ <previous_time_step>
1152+ <exclude_from_stat/>
1153+ </previous_time_step>
1154+ <nonlinear_field>
1155+ <exclude_from_stat/>
1156+ </nonlinear_field>
1157+ </stat>
1158+ <convergence>
1159+ <include_in_convergence/>
1160+ </convergence>
1161+ <detectors>
1162+ <include_in_detectors/>
1163+ </detectors>
1164+ <steady_state>
1165+ <include_in_steady_state/>
1166+ </steady_state>
1167+ <consistent_interpolation/>
1168+ </prognostic>
1169+ </vector_field>
1170+ <scalar_field name="FreeSurface" rank="0">
1171+ <diagnostic>
1172+ <algorithm name="Internal" material_phase_support="multiple"/>
1173+ <mesh name="PressureMesh"/>
1174+ <output/>
1175+ <stat/>
1176+ <convergence>
1177+ <include_in_convergence/>
1178+ </convergence>
1179+ <detectors>
1180+ <include_in_detectors/>
1181+ </detectors>
1182+ <steady_state>
1183+ <include_in_steady_state/>
1184+ </steady_state>
1185+ </diagnostic>
1186+ </scalar_field>
1187+ <scalar_field name="AnalyticFreeSurface" rank="0">
1188+ <prescribed>
1189+ <mesh name="VelocityMesh"/>
1190+ <value name="WholeMesh">
1191+ <python>
1192+ <string_value lines="20" type="python">def val(X,t):
1193+ import height
1194+ return height.function([X[0],X[1]])</string_value>
1195+ </python>
1196+ </value>
1197+ <output/>
1198+ <stat/>
1199+ <detectors>
1200+ <exclude_from_detectors/>
1201+ </detectors>
1202+ </prescribed>
1203+ </scalar_field>
1204+ </material_phase>
1205+</fluidity_options>
1206
1207=== added file 'tests/netcdf_read_free_surface/netcdf_read_free_surface.xml'
1208--- tests/netcdf_read_free_surface/netcdf_read_free_surface.xml 1970-01-01 00:00:00 +0000
1209+++ tests/netcdf_read_free_surface/netcdf_read_free_surface.xml 2012-02-11 17:18:19 +0000
1210@@ -0,0 +1,49 @@
1211+<?xml version="1.0" encoding="UTF-8" ?>
1212+<testproblem>
1213+ <name>netcdf_read_free_surface</name>
1214+ <owner userid="asc"/>
1215+ <tags>flml netcdf</tags>
1216+ <problem_definition length="medium" nprocs="1">
1217+ <command_line>fluidity -v3 -l netcdf_read_free_surface.flml</command_line>
1218+ </problem_definition>
1219+ <variables>
1220+ <variable name="max_freesurface_error" language="python">
1221+import vtktools
1222+
1223+# Read output file
1224+u = vtktools.vtu("netcdf_read_free_surface_0.vtu")
1225+xyz = u.GetLocations()
1226+f = u.GetField("FreeSurface")
1227+af = u.GetField("AnalyticFreeSurface")
1228+err = f - af
1229+
1230+#xmin = min(xyz[:,0])
1231+#xmax = max(xyz[:,0])
1232+#ymin = min(xyz[:,1])
1233+#ymax = max(xyz[:,1])
1234+#ztop = max(xyz[:,2])
1235+#
1236+## Focus on top surface interior
1237+#for i in range(len(err)):
1238+# # Free surface not currently initialised correctly on bottom - investigate
1239+# if (xyz[i,1] != ztop):
1240+# err[i] = 0.0
1241+# # Free surface not currently initialised correctly on the boundary - investigate
1242+# if ((xyz[i,0] == xmin) or (xyz[i,0] == xmax) or (xyz[i,1] == ymin) or (xyz[i,1] == ymax)):
1243+# err[i] = 0.0
1244+
1245+# Write out error field for debugging
1246+u.AddScalarField('Error', err)
1247+u.Write('error.vtu')
1248+
1249+max_freesurface_error = max(abs(err))
1250+ </variable>
1251+ </variables>
1252+ <pass_tests>
1253+ <test name="Checking difference is smaller than 1e-10" language="python">
1254+assert ( max_freesurface_error &lt; 1e-10 )
1255+ </test>
1256+ </pass_tests>
1257+ <warn_tests>
1258+ </warn_tests>
1259+</testproblem>