diff --git a/xios_examples/ugrid_projected/Makefile b/xios_examples/ugrid_projected/Makefile
new file mode 100644
index 0000000..b5e888c
--- /dev/null
+++ b/xios_examples/ugrid_projected/Makefile
@@ -0,0 +1,34 @@
+# Make file for the write demonstartion XIOS programme
+# Targets provided our detailed below...
+#
+# all: (default) Build the write programme
+# clean: Delete all final products and working files
+# run: run the programme
+#
+# Environment Variables expected by this MakeFile:
+#
+# FC: mpif90
+# FCFLAGS: -g & include files for netcdf & xios
+# LD_FLAGS: for xios, netcdf, netcdff, stfc++
+# LD_LIBRARY_PATH: for netCDF & XIOS libs
+# XIOS_BINDIR: The directory for XIOS binary files
+
+.PHONY: all, clean, run
+
+all: write
+
+# fortran compilation
+%.o: %.F90
+ $(FC) $(FCFLAGS) -c $<
+
+# fortran linking
+write: write.o
+ $(FC) -o write.exe write.o $(LDFLAGS) \
+ && ln -fs $(XIOS_BINDIR)/xios_server.exe .
+
+run:
+ mpiexec -n 1 ./write.exe : -n 1 ./xios_server.exe
+
+# cleanup
+clean:
+ rm -f *.exe *.o *.mod *.MOD *.out *.err
diff --git a/xios_examples/ugrid_projected/Readme.md b/xios_examples/ugrid_projected/Readme.md
new file mode 100644
index 0000000..a6764ef
--- /dev/null
+++ b/xios_examples/ugrid_projected/Readme.md
@@ -0,0 +1,3 @@
+Demonstration of basic UGrid domain specification.
+
+Read mesh from file then create output mesh to add data to.
diff --git a/xios_examples/ugrid_projected/__init__.py b/xios_examples/ugrid_projected/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/xios_examples/ugrid_projected/axis_check.xml b/xios_examples/ugrid_projected/axis_check.xml
new file mode 100644
index 0000000..1a19131
--- /dev/null
+++ b/xios_examples/ugrid_projected/axis_check.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xios_examples/ugrid_projected/iodef.xml b/xios_examples/ugrid_projected/iodef.xml
new file mode 100644
index 0000000..37acd4d
--- /dev/null
+++ b/xios_examples/ugrid_projected/iodef.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/xios_examples/ugrid_projected/main.xml b/xios_examples/ugrid_projected/main.xml
new file mode 100644
index 0000000..0bebc4b
--- /dev/null
+++ b/xios_examples/ugrid_projected/main.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xios_examples/ugrid_projected/planar_mesh.cdl b/xios_examples/ugrid_projected/planar_mesh.cdl
new file mode 100644
index 0000000..02a9db2
--- /dev/null
+++ b/xios_examples/ugrid_projected/planar_mesh.cdl
@@ -0,0 +1,170 @@
+netcdf planar_mesh {
+dimensions:
+ One = 1 ;
+ Two = 2 ;
+ Four = 4 ;
+ nmesh_node = 21 ;
+ nmesh_edge = 32 ;
+ nmesh_face = 12 ;
+variables:
+ int mesh ;
+ mesh:cf_role = "mesh_topology" ;
+ mesh:geometry = "planar" ;
+ mesh:topology = "non_periodic" ;
+ mesh:coord_sys = "xyz" ;
+ mesh:periodic_x = "F" ;
+ mesh:periodic_y = "F" ;
+ mesh:constructor_inputs = "geometry=planar;topology=non_periodic;coord_sys=xyz;edge_cells_x=6;edge_cells_y=2;periodic_x=F;periodic_y=F;domain_size=[6.00,2.00];domain_centre=[9000.00,7000.00]" ;
+ mesh:max_stencil_depth = 0 ;
+ mesh:n_mesh_maps = 0 ;
+ mesh:long_name = "Topology data of 2D unstructured mesh" ;
+ mesh:topology_dimension = 2 ;
+ mesh:node_coordinates = "mesh_node_x mesh_node_y" ;
+ mesh:face_coordinates = "mesh_face_x mesh_face_y" ;
+ mesh:face_node_connectivity = "mesh_face_nodes" ;
+ mesh:edge_node_connectivity = "mesh_edge_nodes" ;
+ mesh:face_edge_connectivity = "mesh_face_edges" ;
+ mesh:face_face_connectivity = "mesh_face_links" ;
+ mesh:domain_extents = "mesh_domain_extents" ;
+ mesh:npanels = 1 ;
+ int mesh_face_nodes(nmesh_face, Four) ;
+ mesh_face_nodes:cf_role = "face_node_connectivity" ;
+ mesh_face_nodes:long_name = "Maps every quadrilateral face to its four corner nodes." ;
+ mesh_face_nodes:start_index = 1 ;
+ int mesh_face_edges(nmesh_face, Four) ;
+ mesh_face_edges:cf_role = "face_edge_connectivity" ;
+ mesh_face_edges:long_name = "Maps every quadrilateral face to its four edges." ;
+ mesh_face_edges:start_index = 1 ;
+ int mesh_face_links(nmesh_face, Four) ;
+ mesh_face_links:cf_role = "face_face_connectivity" ;
+ mesh_face_links:long_name = "Indicates which other faces neighbour each face." ;
+ mesh_face_links:start_index = 1 ;
+ mesh_face_links:_FillValue = -9999 ;
+ int mesh_edge_nodes(nmesh_edge, Two) ;
+ mesh_edge_nodes:cf_role = "edge_node_connectivity" ;
+ mesh_edge_nodes:long_name = "Maps every edge to the two nodes that it connects." ;
+ mesh_edge_nodes:start_index = 1 ;
+ double mesh_node_x(nmesh_node) ;
+ mesh_node_x:standard_name = "projection_x_coordinate" ;
+ mesh_node_x:long_name = "x coordinate of 2D mesh nodes." ;
+ mesh_node_x:units = "m" ;
+ double mesh_node_y(nmesh_node) ;
+ mesh_node_y:standard_name = "projection_y_coordinate" ;
+ mesh_node_y:long_name = "y coordinate of 2D mesh nodes." ;
+ mesh_node_y:units = "m" ;
+ double mesh_face_x(nmesh_face) ;
+ mesh_face_x:standard_name = "projection_x_coordinate" ;
+ mesh_face_x:long_name = "x coordinate of 2D face centres" ;
+ mesh_face_x:units = "m" ;
+ double mesh_face_y(nmesh_face) ;
+ mesh_face_y:standard_name = "projection_y_coordinate" ;
+ mesh_face_y:long_name = "y coordinate of 2D face centres" ;
+ mesh_face_y:units = "m" ;
+ double mesh_domain_extents(Four, Two) ;
+ double node_empty_data_container(nmesh_node) ;
+ node_empty_data_container:coordinates = "mesh_node_y mesh_node_x" ;
+ double face_empty_data_container(nmesh_face) ;
+ face_empty_data_container:coordinates = "mesh_face_y mesh_face_x" ;
+ double edge_empty_data_container(nmesh_edge) ;
+
+// global attributes:
+ :Conventions = "CF-1.6 UGRID-1.0" ;
+
+data:
+
+ mesh = _ ;
+
+ mesh_face_nodes =
+ 1, 2, 3, 4,
+ 2, 5, 6, 3,
+ 5, 7, 8, 6,
+ 7, 9, 10, 8,
+ 9, 11, 12, 10,
+ 11, 13, 14, 12,
+ 15, 16, 2, 1,
+ 16, 17, 5, 2,
+ 17, 18, 7, 5,
+ 18, 19, 9, 7,
+ 19, 20, 11, 9,
+ 20, 21, 13, 11 ;
+
+ mesh_face_edges =
+ 1, 2, 3, 4,
+ 3, 5, 6, 7,
+ 6, 8, 9, 10,
+ 9, 11, 12, 13,
+ 12, 14, 15, 16,
+ 15, 17, 18, 19,
+ 20, 21, 22, 2,
+ 22, 23, 24, 5,
+ 24, 25, 26, 8,
+ 26, 27, 28, 11,
+ 28, 29, 30, 14,
+ 30, 31, 32, 17 ;
+
+ mesh_face_links =
+ _, 7, 2, _,
+ 1, 8, 3, _,
+ 2, 9, 4, _,
+ 3, 10, 5, _,
+ 4, 11, 6, _,
+ 5, 12, _, _,
+ _, _, 8, 1,
+ 7, _, 9, 2,
+ 8, _, 10, 3,
+ 9, _, 11, 4,
+ 10, _, 12, 5,
+ 11, _, _, 6 ;
+
+ mesh_edge_nodes =
+ 4, 1,
+ 1, 2,
+ 3, 2,
+ 4, 3,
+ 2, 5,
+ 6, 5,
+ 3, 6,
+ 5, 7,
+ 8, 7,
+ 6, 8,
+ 7, 9,
+ 10, 9,
+ 8, 10,
+ 9, 11,
+ 12, 11,
+ 10, 12,
+ 11, 13,
+ 14, 13,
+ 12, 14,
+ 1, 15,
+ 15, 16,
+ 2, 16,
+ 16, 17,
+ 5, 17,
+ 17, 18,
+ 7, 18,
+ 18, 19,
+ 9, 19,
+ 19, 20,
+ 11, 20,
+ 20, 21,
+ 13, 21 ;
+
+ mesh_node_x = 8997, 8998, 8998, 8997, 8999, 8999, 9000, 9000, 9001, 9001,
+ 9002, 9002, 9003, 9003, 8997, 8998, 8999, 9000, 9001, 9002, 9003 ;
+
+ mesh_node_y = 7000, 7000, 7001, 7001, 7000, 7001, 7000, 7001, 7000, 7001,
+ 7000, 7001, 7000, 7001, 6999, 6999, 6999, 6999, 6999, 6999, 6999 ;
+
+ mesh_face_x = 8997.5, 8998.5, 8999.5, 9000.5, 9001.5, 9002.5, 8997.5,
+ 8998.5, 8999.5, 9000.5, 9001.5, 9002.5 ;
+
+ mesh_face_y = 7000.5, 7000.5, 7000.5, 7000.5, 7000.5, 7000.5, 6999.5,
+ 6999.5, 6999.5, 6999.5, 6999.5, 6999.5 ;
+
+ mesh_domain_extents =
+ 8997, 6999,
+ 9003, 6999,
+ 9003, 7001,
+ 8997, 7001 ;
+}
diff --git a/xios_examples/ugrid_projected/test_write_metadata.py b/xios_examples/ugrid_projected/test_write_metadata.py
new file mode 100644
index 0000000..9265e88
--- /dev/null
+++ b/xios_examples/ugrid_projected/test_write_metadata.py
@@ -0,0 +1,53 @@
+import copy
+import glob
+import netCDF4
+import numpy as np
+import os
+import subprocess
+import unittest
+
+import xios_examples.shared_testing as xshared
+
+this_path = os.path.realpath(__file__)
+this_dir = os.path.dirname(this_path)
+
+class TestWriteMetadata(xshared._TestCase):
+ test_dir = this_dir
+ transient_inputs = ['cubedsphere_mesh.nc']
+ transient_outputs = ['data_output.nc']
+ executable = './write.exe'
+ mesh_file_cdl = 'planar_mesh.cdl'
+
+ @classmethod
+ def make_a_write_test(cls, inf, nclients=1, nservers=1):
+ """
+ this function makes a test case and returns it as a test function,
+ suitable to be dynamically added to a TestCase for running.
+
+ """
+ # always copy for value, don't pass by reference.
+ infcp = copy.copy(inf)
+ # expected by the fortran XIOS program's main.xml
+ inputfile = cls.transient_inputs[0]
+ outputfile = cls.transient_outputs[0]
+ @unittest.skipIf(os.environ.get('MVER', '') != 'XIOS3/trunk',
+ "skipping for XIOS2 as XIOS3 syntax used")
+ def test_write_metadata(self):
+ # create a netCDF file using nc_method
+ cls.make_netcdf(infcp, inputfile)
+ cls.run_mpi_xios(nclients=nclients, nservers=nservers)
+
+ # load the result netCDF file
+ runfile = '{}/{}'.format(cls.test_dir, outputfile)
+ assert(os.path.exists(runfile))
+ return test_write_metadata
+
+f = f'{this_dir}/planar_mesh.cdl'
+# unique name for the test
+tname = 'test_{}'.format(os.path.splitext(os.path.basename(f))[0])
+# add the test as an attribute (function) to the test class
+
+# !!! remove this limit on success
+if os.environ.get('MVER', '').startswith('XIOS3/trunk'):
+ setattr(TestWriteMetadata, tname,
+ TestWriteMetadata.make_a_write_test(f, nclients=1))
diff --git a/xios_examples/ugrid_projected/write.F90 b/xios_examples/ugrid_projected/write.F90
new file mode 100644
index 0000000..8577f79
--- /dev/null
+++ b/xios_examples/ugrid_projected/write.F90
@@ -0,0 +1,322 @@
+!-----------------------------------------------------------------------------
+! (C) Crown copyright 2025 Met Office. All rights reserved.
+! The file LICENCE, distributed with this code, contains details of the terms
+! under which the code may be used.
+!-----------------------------------------------------------------------------
+!> Programme to just write data with coordinate system definition metadata.
+!>
+program write
+ use xios
+ use mpi
+ USE, INTRINSIC :: ISO_C_BINDING
+ use iso_fortran_env, only : output_unit
+
+ implicit none
+
+ integer :: comm = -1
+ integer :: rank = -1
+ integer :: npar = 0
+
+ call initialise()
+ call simulate()
+ call finalise()
+contains
+
+ subroutine initialise()
+
+ type(xios_date) :: origin
+ type(xios_date) :: start
+ type(xios_duration) :: tstep
+ integer :: mpi_error
+ integer :: len_node, ni_node, ibegin_node
+ integer :: len_face, ni_face, ibegin_face
+ integer :: len_edge, ni_edge, ibegin_edge
+ integer :: fcount, ecount, fvcount, evcount
+ integer :: fvertex_len, evertex_len, fvertex_n, evertex_n
+ double precision, dimension (:), allocatable :: node_y_vals, node_x_vals, &
+ face_y_vals, face_x_vals, &
+ edge_y_vals, edge_x_vals
+ double precision, dimension (:,:), allocatable :: face_y_bounds, face_x_bounds, &
+ edge_y_bounds, edge_x_bounds, &
+ mesh_face_nodes_dbl, mesh_edge_nodes_dbl, &
+ inbfx, inbfy
+ integer, dimension (:,:), allocatable :: mesh_face_nodes, mesh_edge_nodes
+ character(len=64) :: t_origin
+
+ origin = xios_date(2022, 2, 2, 12, 0, 0)
+ start = xios_date(2022, 12, 13, 12, 0, 0)
+ tstep = xios_hour
+
+ ! Initialise MPI and XIOS
+ call MPI_INIT(mpi_error)
+ call xios_initialize('client', return_comm=comm)
+
+ call MPI_Comm_rank(comm, rank, mpi_error)
+ call MPI_Comm_size(comm, npar, mpi_error)
+
+ ! use the axis_check context to obtain sizing information on all arrays
+ ! for use in defining the main context interpretation
+
+ print *, 'rank:', rank, ' ', "initialising axis_check"
+ flush(output_unit)
+ call xios_context_initialize('axis_check', comm)
+ call xios_set_time_origin(origin)
+ call xios_set_start_date(start)
+ call xios_set_timestep(tstep)
+
+ call xios_close_context_definition()
+ print *, 'rank:', rank, ' ', "axis_check initialised"
+ flush(output_unit)
+
+ ! fetch sizes of axes from the input file for allocate
+ call xios_get_domain_attr('cndata::', ni_glo=len_node, ni=ni_node, ibegin=ibegin_node)
+ call xios_get_domain_attr('cfdata::', ni_glo=len_face, ni=ni_face, ibegin=ibegin_face)
+ call xios_get_domain_attr('cedata::', ni_glo=len_edge, ni=ni_edge, ibegin=ibegin_edge)
+ call xios_get_axis_attr('mesh_face_nodes::[0]', n_glo=fvertex_len, n=fvertex_n)
+ print *, 'rank:', rank, ' ', "fvertex length: ", fvertex_len
+ call xios_get_axis_attr('mesh_edge_nodes::[0]', n_glo=evertex_len, n=evertex_n)
+ print *, 'rank:', rank, ' ', "evertex length: ", evertex_len
+
+ allocate ( node_x_vals(ni_node) )
+ allocate ( node_y_vals(ni_node) )
+ allocate ( face_x_vals(ni_face) )
+ allocate ( face_y_vals(ni_face) )
+ allocate ( edge_x_vals(ni_edge) )
+ allocate ( edge_y_vals(ni_edge) )
+ allocate ( mesh_face_nodes(fvertex_len, ni_face) )
+ allocate ( mesh_face_nodes_dbl(fvertex_len, ni_face) )
+ allocate ( mesh_edge_nodes(evertex_len, ni_edge) )
+ allocate ( mesh_edge_nodes_dbl(evertex_len, ni_edge) )
+ allocate ( face_y_bounds(fvertex_len, ni_face) )
+ allocate ( face_x_bounds(fvertex_len, ni_face) )
+ allocate ( edge_y_bounds(evertex_len, ni_edge) )
+ allocate ( edge_x_bounds(evertex_len, ni_edge) )
+ print *, 'rank:', rank, ' ', 'ni_node= ', ni_node
+ print *, 'rank:', rank, ' ', 'ni_face= ', ni_face
+ print *, 'rank:', rank, ' ', 'ni_edge= ', ni_edge
+ print *, 'rank:', rank, ' ', 'fvertices: ', fvertex_len
+ flush(output_unit)
+
+ allocate ( inbfx(fvertex_len, ni_face) )
+ allocate ( inbfy(fvertex_len, ni_face) )
+ ! print *, 'get bounds'
+ ! flush(output_unit)
+ ! call xios_get_domain_attr('cfdata::', bounds_lon_1d=inbfx, bounds_lat_1d=inbfy)
+ ! print *, 'inbfx=', inbfx
+ ! print *, 'inbfy=', inbfy
+
+ print *, 'get coordinate values'
+ flush(output_unit)
+ ! fetch coordinate value arrays from the input file
+ call xios_get_domain_attr('cndata::', lonvalue_1d=node_x_vals, latvalue_1d=node_y_vals)
+ call xios_get_domain_attr('cfdata::', lonvalue_1d=face_x_vals, latvalue_1d=face_y_vals)
+ !call xios_get_domain_attr('cedata::', lonvalue_1d=edge_x_vals, latvalue_1d=edge_y_vals)
+ print *, 'rank:', rank, ' ', 'node xvals= ', node_x_vals
+ print *, 'rank:', rank, ' ', 'node yvals= ', node_y_vals
+ print *, 'rank:', rank, ' ', 'face xvals= ', face_x_vals
+ print *, 'rank:', rank, ' ', 'face yvals= ', face_y_vals
+ !print *, 'rank:', rank, ' ', 'edge xvals= ', edge_x_vals, 'edge yvals= ', edge_y_vals
+ flush(output_unit)
+
+ call xios_recv_field("mesh_face_nodes", mesh_face_nodes_dbl)
+ mesh_face_nodes = int(mesh_face_nodes_dbl)
+
+ print *, 'rank:', rank, ' ', 'mesh_face_nodes= ', mesh_face_nodes
+ flush(output_unit)
+
+ do fvcount=1, fvertex_len
+ do fcount=1, ni_face
+ ! print *, 'rank:', rank, ' ', mesh_face_nodes(fvcount, fcount)
+ print *, 'rank:', rank, ' ', 'fvcount=', fvcount, 'fcount=', fcount
+ face_x_bounds(fvcount, fcount) = node_x_vals(mesh_face_nodes(fvcount, fcount))
+ face_y_bounds(fvcount, fcount) = node_y_vals(mesh_face_nodes(fvcount, fcount))
+ end do
+
+ end do
+ print *, 'rank:', rank, ' ', "face_x_bounds: ", shape(face_x_bounds)
+ print *, 'rank:', rank, ' ', face_x_bounds
+ print *, 'rank:', rank, ' ', "face_y_bounds: ", shape(face_y_bounds)
+ print *, 'rank:', rank, ' ', face_y_bounds
+
+ call xios_recv_field("mesh_edge_nodes", mesh_edge_nodes_dbl)
+ mesh_edge_nodes = int(mesh_edge_nodes_dbl)
+ print *, 'rank:', rank, ' ', "mesh_edge_nodes", mesh_edge_nodes
+
+ do ecount=1, ni_edge
+ do evcount=1, evertex_len
+ edge_x_bounds(evcount, ecount) = node_x_vals(mesh_edge_nodes(evcount, ecount))
+ edge_y_bounds(evcount, ecount) = node_y_vals(mesh_edge_nodes(evcount, ecount))
+ end do
+ edge_x_vals(ecount) = edge_x_bounds(1, ecount) - 0.5 * &
+ (edge_x_bounds(1, ecount) - edge_x_bounds(2, ecount))
+ edge_y_vals(ecount) = edge_y_bounds(1, ecount) - 0.5 * &
+ (edge_y_bounds(1, ecount) - edge_y_bounds(2, ecount))
+ end do
+ print *, 'rank:', rank, ' ', "edge_x: ", shape(edge_x_vals), edge_x_vals
+ print *, 'rank:', rank, ' ', "edge_x_bounds: ", shape(edge_x_bounds)
+ print *, 'rank:', rank, ' ', edge_x_bounds(1, :)
+ print *, 'rank:', rank, ' ', edge_x_bounds(2, :)
+ print *, 'rank:', rank, ' ', "edge_y: ", shape(edge_y_vals), edge_y_vals
+ print *, 'rank:', rank, ' ', "edge_y_bounds: ", shape(edge_y_bounds)
+ print *, 'rank:', rank, ' ', edge_y_bounds(1, :)
+ print *, 'rank:', rank, ' ', edge_y_bounds(2, :)
+
+
+ ! finalise axis_check context, it no longer in use
+ ! call xios_set_current_context('axis_check')
+ call xios_context_finalize()
+ print *, 'rank:', rank, ' ', "axis check finalised successfully"
+ flush(output_unit)
+
+ ! initialize the main context for interacting with the data.
+ print *, 'rank:', rank, ' ', "initialising main context"
+ flush(output_unit)
+ call xios_context_initialize('main', comm)
+
+ call xios_set_time_origin(origin)
+ call xios_set_start_date(start)
+ call xios_set_timestep(tstep)
+
+ ! define the horizontal domain and vertical axis using the input file values
+
+ print *, 'rank:', rank, ' ', "now define domain configuration from input mesh"
+ flush(output_unit)
+ print *, 'rank:', rank, ' ', 'ibegin_node=', ibegin_node, ' ; ni_node=', ni_node
+ print *, 'rank:', rank, ' ', 'nodes: x, y'
+ print *, 'rank:', rank, ' ', node_x_vals(ibegin_node+1:(ibegin_node+ni_node))
+ print *, 'rank:', rank, ' ', node_y_vals(ibegin_node+1:(ibegin_node+ni_node))
+ print *, 'rank:', rank, ' ', 'faces'
+ print *, 'rank:', rank, ' ', face_x_vals(ibegin_face+1:(ibegin_face+ni_face))
+ print *, 'rank:', rank, ' ', face_y_vals(ibegin_face+1:(ibegin_face+ni_face))
+ print *, 'rank:', rank, ' ', 'face bounds'
+ print *, 'rank:', rank, ' ', face_x_bounds(:,ibegin_face+1:(ibegin_face+ni_face))
+ print *, 'rank:', rank, ' ', face_y_bounds(:,ibegin_face+1:(ibegin_face+ni_face))
+ print *, 'rank:', rank, ' ', 'edges'
+ print *, 'rank:', rank, ' ', edge_x_vals(ibegin_edge+1:(ibegin_edge+ni_edge))
+ print *, 'rank:', rank, ' ', edge_y_vals(ibegin_edge+1:(ibegin_edge+ni_edge))
+ print *, 'rank:', rank, ' ', 'edge bounds'
+ print *, 'rank:', rank, ' ', edge_x_bounds(:,ibegin_edge+1:(ibegin_edge+ni_edge))
+ print *, 'rank:', rank, ' ', edge_y_bounds(:,ibegin_edge+1:(ibegin_edge+ni_edge))
+ call xios_set_domain_attr("node_domain", ni_glo=len_node, ni=ni_node, ibegin=ibegin_node, &
+ nj_glo=len_node, nj=ni_node, jbegin=ibegin_node, &
+ latvalue_1d=node_y_vals(ibegin_node+1:(ibegin_node+ni_node)), &
+ lonvalue_1d=node_x_vals(ibegin_node+1:(ibegin_node+ni_node)))
+ call xios_set_domain_attr("face_domain", ni_glo=len_face, ni=ni_face, ibegin=ibegin_face, &
+ nj_glo=len_face, nj=ni_face, jbegin=ibegin_face, &
+ latvalue_1d=face_y_vals(ibegin_face+1:(ibegin_face+ni_face)), &
+ lonvalue_1d=face_x_vals(ibegin_face+1:(ibegin_face+ni_face)), &
+ bounds_lat_1d=face_y_bounds(:,ibegin_face+1:(ibegin_face+ni_face)), &
+ bounds_lon_1d=face_x_bounds(:,ibegin_face+1:(ibegin_face+ni_face)))
+ call xios_set_domain_attr("edge_domain", ni_glo=len_edge, ni=ni_edge, ibegin=ibegin_edge, &
+ nj_glo=len_edge, nj=ni_edge, jbegin=ibegin_edge, &
+ latvalue_1d=edge_y_vals(ibegin_edge+1:(ibegin_edge+ni_edge)), &
+ lonvalue_1d=edge_x_vals(ibegin_edge+1:(ibegin_edge+ni_edge)), &
+ bounds_lat_1d=edge_y_bounds(:,ibegin_edge+1:(ibegin_edge+ni_edge)), &
+ bounds_lon_1d=edge_x_bounds(:,ibegin_edge+1:(ibegin_edge+ni_edge)))
+
+ print *, 'rank:', rank, ' ', "ready to close main context definition"
+ flush(output_unit)
+
+
+ call xios_close_context_definition()
+ print *, 'rank:', rank, ' ', "main context defined successfully"
+ flush(output_unit)
+ call xios_get_domain_attr('ndata::', lonvalue_1d=node_x_vals, latvalue_1d=node_y_vals)
+ print *, 'rank:', rank, ' ', "output node x = ", node_x_vals
+ print *, 'rank:', rank, ' ', "output node y = ", node_y_vals
+ flush(output_unit)
+ call xios_get_domain_attr('fdata::', lonvalue_1d=face_x_vals, latvalue_1d=face_y_vals)
+ print *, 'rank:', rank, ' ', "output face x = ", face_x_vals
+ print *, 'rank:', rank, ' ', "output face y = ", face_y_vals
+ flush(output_unit)
+
+ deallocate (node_x_vals)
+ deallocate (node_y_vals)
+ deallocate (face_x_vals)
+ deallocate (face_y_vals)
+ deallocate (edge_x_vals)
+ deallocate (edge_y_vals)
+ deallocate (face_y_bounds)
+ deallocate (face_x_bounds)
+ deallocate (edge_y_bounds)
+ deallocate (edge_x_bounds)
+ deallocate (mesh_face_nodes_dbl)
+ deallocate (mesh_face_nodes)
+ print *, 'rank:', rank, ' ', "deallocations"
+ end subroutine initialise
+
+ subroutine finalise()
+
+ integer :: mpi_error
+
+ ! Finalise all XIOS contexts and MPI
+ print *, 'rank:', rank, ' ', "finalising"
+ flush(output_unit)
+ call xios_set_current_context('main')
+ call xios_context_finalize()
+ print *, 'rank:', rank, ' ', "finalised main"
+ flush(output_unit)
+ call xios_finalize()
+ print *, 'rank:', rank, ' ', "finalised xios"
+ flush(output_unit)
+ call MPI_Finalize(mpi_error)
+
+ end subroutine finalise
+
+ subroutine simulate()
+
+ type(xios_date) :: start
+ type(xios_date) :: current
+ integer :: ts
+ integer :: i
+ integer :: len_node
+ integer :: len_edge
+ integer :: len_face
+ double precision :: frtv
+
+ ! Allocatable arrays, size is taken from input file
+ double precision, dimension (:), allocatable :: node_data, face_data, edge_data
+
+ print *, 'rank:', rank, ' ', "simulation"
+ ! obtain sizing of the grid for the array allocation
+ call xios_get_domain_attr('ndata::', ni=len_node)
+ call xios_get_domain_attr('fdata::', ni=len_face)
+ call xios_get_domain_attr('edata::', ni=len_edge)
+
+ allocate ( node_data(len_node) )
+ allocate ( face_data(len_face) )
+ allocate ( edge_data(len_edge) )
+ print *, 'rank:', rank, ' ', 'len_node= ', len_node
+ print *, 'rank:', rank, ' ', 'len_face= ', len_face
+ print *, 'rank:', rank, ' ', 'len_edge= ', len_edge
+ flush(output_unit)
+
+ do ts=1, 2
+ call xios_update_calendar(ts)
+ call xios_get_current_date(current)
+ do i=1, len_node
+ node_data(i) = ts
+ end do
+ call xios_send_field('ndata', node_data)
+
+ do i=1, len_face
+ face_data(i) = 10 * ts
+ end do
+ call xios_send_field('fdata', face_data)
+
+ do i=1, len_edge
+ edge_data(i) = 100 * ts
+ end do
+ call xios_send_field('edata', edge_data)
+
+ enddo
+
+ deallocate (node_data)
+ deallocate (face_data)
+ deallocate (edge_data)
+ print *, 'rank:', rank, ' ', "fields sent, exiting simulation"
+ flush(output_unit)
+
+ end subroutine simulate
+
+end program write
diff --git a/xios_examples/ugrid_projected/xios.xml b/xios_examples/ugrid_projected/xios.xml
new file mode 100644
index 0000000..9ec1df0
--- /dev/null
+++ b/xios_examples/ugrid_projected/xios.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ performance
+
+
+ 1.0
+
+
+
+
+ true
+
+ 100
+
+
+ true
+
+
+
+