From be5e5d26f2960102dc235c1c8133ed3aff12df13 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 27 Aug 2021 12:12:43 -0400 Subject: [PATCH] Enabled non-unique character coordinate name to bodies. Tested in REAL8 mode, but does not yet work in NetCDF --- python/swiftest/swiftest/io.py | 36 ++++++++++--- src/io/io.f90 | 8 +-- src/modules/swiftest_classes.f90 | 53 ++++++++++--------- src/modules/swiftest_globals.f90 | 2 + src/netcdf/netcdf.f90 | 90 +++++++++++++++++--------------- 5 files changed, 112 insertions(+), 77 deletions(-) diff --git a/python/swiftest/swiftest/io.py b/python/swiftest/swiftest/io.py index a8c2daf08..35d22f5b3 100644 --- a/python/swiftest/swiftest/io.py +++ b/python/swiftest/swiftest/io.py @@ -468,6 +468,7 @@ def swiftest_stream(f, param): tlab : string list Labels for the tvec data """ + NAMELEN = 32 while True: # Loop until you read the end of file try: # Read multi-line header @@ -478,6 +479,9 @@ def swiftest_stream(f, param): ntp = f.read_ints() iout_form = f.read_reals('c') cbid = f.read_ints() + dtstr = f'a{NAMELEN}' + cbnames = f.read_record(dtstr) + cbnames = [np.char.strip(str(cbnames[0], encoding='utf-8'))] Mcb = f.read_reals(np.float64) Rcb = f.read_reals(np.float64) J2cb = f.read_reals(np.float64) @@ -494,6 +498,11 @@ def swiftest_stream(f, param): Qcb = f.read_reals(np.float64) if npl[0] > 0: plid = f.read_ints() + dtstr = f'({npl[0]},)a{NAMELEN}' + names = f.read_record(np.dtype(dtstr)) + plnames = [] + for i in range(npl[0]): + plnames.append(np.char.strip(str(names[i], encoding='utf-8'))) p1 = f.read_reals(np.float64) p2 = f.read_reals(np.float64) p3 = f.read_reals(np.float64) @@ -523,6 +532,11 @@ def swiftest_stream(f, param): Qpl = f.read_reals(np.float64) if ntp[0] > 0: tpid = f.read_ints() + dtstr = f'({ntp[0]},)a{NAMELEN}' + names = f.read_record(np.dtype(dtstr)) + tpnames = [] + for i in range(npl[0]): + tpnames.append(np.char.strip(str(names[i], encoding='utf-8'))) t1 = f.read_reals(np.float64) t2 = f.read_reals(np.float64) t3 = f.read_reals(np.float64) @@ -550,6 +564,7 @@ def swiftest_stream(f, param): else: pvec = np.empty((8, 0)) plid = np.empty(0) + plnames = np.empty(0) if ntp > 0: tvec = np.vstack([t1, t2, t3, t4, t5, t6]) if param['OUT_FORM'] == 'XVEL': @@ -560,6 +575,7 @@ def swiftest_stream(f, param): else: tvec = np.empty((6, 0)) tpid = np.empty(0) + tpnames = np.empty(0) cvec = np.array([Mcb, Rcb, J2cb, J4cb]) if param['RHILL_PRESENT'] == 'YES': if npl > 0: @@ -572,9 +588,9 @@ def swiftest_stream(f, param): cvec = np.vstack([cvec, k2cb, Qcb]) if npl > 0: pvec = np.vstack([pvec, k2pl, Qpl]) - yield t, cbid, cvec.T, clab, \ - npl, plid, pvec.T, plab, \ - ntp, tpid, tvec.T, tlab + yield t, cbid, cbnames, cvec.T, clab, \ + npl, plid, plnames, pvec.T, plab, \ + ntp, tpid, tpnames, tvec.T, tlab def swifter2xr(param): @@ -638,24 +654,30 @@ def swiftest2xr(param): cb = [] pl = [] tp = [] + cbn = None try: with FortranFile(param['BIN_OUT'], 'r') as f: - for t, cbid, cvec, clab, \ - npl, plid, pvec, plab, \ - ntp, tpid, tvec, tlab in swiftest_stream(f, param): + for t, cbid, cbnames, cvec, clab, \ + npl, plid, plnames, pvec, plab, \ + ntp, tpid, tpnames, tvec, tlab in swiftest_stream(f, param): # Prepare frames by adding an extra axis for the time coordinate cbframe = np.expand_dims(cvec, axis=0) plframe = np.expand_dims(pvec, axis=0) tpframe = np.expand_dims(tvec, axis=0) + # Create xarray DataArrays out of each body type cbxr = xr.DataArray(cbframe, dims=dims, coords={'time': t, 'id': cbid, 'vec': clab}) + cbxr = cbxr.assign_coords(name=("id", cbnames)) plxr = xr.DataArray(plframe, dims=dims, coords={'time': t, 'id': plid, 'vec': plab}) + plxr = plxr.assign_coords(name=("id", plnames)) tpxr = xr.DataArray(tpframe, dims=dims, coords={'time': t, 'id': tpid, 'vec': tlab}) - + tpxr = tpxr.assign_coords(name=("id", tpnames)) + cb.append(cbxr) pl.append(plxr) tp.append(tpxr) + sys.stdout.write('\r' + f"Reading in time {t[0]:.3e}") sys.stdout.flush() except IOError: diff --git a/src/io/io.f90 b/src/io/io.f90 index c4c9b8b81..b30718c83 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -1036,7 +1036,7 @@ module function io_read_frame_body(self, iu, param) result(ierr) select case(param%in_type) case (REAL4_TYPE, REAL8_TYPE) read(iu, err = 667, iomsg = errmsg) self%id(:) - !read(iu, err = 667, iomsg = errmsg) self%name(:) + read(iu, err = 667, iomsg = errmsg) self%name(:) select case (param%in_form) case (XV) @@ -1158,7 +1158,7 @@ module function io_read_frame_cb(self, iu, param) result(ierr) character(len=STRMAX) :: errmsg read(iu, err = 667, iomsg = errmsg) self%id - !read(iu, err = 667, iomsg = errmsg) self%name + read(iu, err = 667, iomsg = errmsg) self%name read(iu, err = 667, iomsg = errmsg) self%Gmass self%mass = self%Gmass / param%GU read(iu, err = 667, iomsg = errmsg) self%radius @@ -1473,6 +1473,7 @@ module subroutine io_write_encounter(self, pl, encbody, param) call util_exit(FAILURE) end subroutine io_write_encounter + module subroutine io_write_frame_body(self, iu, param) !! author: David A. Minton !! @@ -1492,6 +1493,7 @@ module subroutine io_write_frame_body(self, iu, param) associate(n => self%nbody) if (n == 0) return write(iu, err = 667, iomsg = errmsg) self%id(1:n) + write(iu, err = 667, iomsg = errmsg) self%name(1:n) if ((param%out_form == XV) .or. (param%out_form == XVEL)) then write(iu, err = 667, iomsg = errmsg) self%xh(1, 1:n) write(iu, err = 667, iomsg = errmsg) self%xh(2, 1:n) @@ -1551,8 +1553,8 @@ module subroutine io_write_frame_cb(self, iu, param) character(len=STRMAX) :: errmsg associate(cb => self) - !write(iu, err = 667, iomsg = errmsg) cb%name write(iu, err = 667, iomsg = errmsg) cb%id + write(iu, err = 667, iomsg = errmsg) cb%name write(iu, err = 667, iomsg = errmsg) cb%Gmass write(iu, err = 667, iomsg = errmsg) cb%radius write(iu, err = 667, iomsg = errmsg) cb%j2rp2 diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 7703dd534..06435cbe7 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -86,10 +86,11 @@ module swiftest_classes type :: netcdf_parameters integer(I4B) :: out_type !! NetCDF output type (will be assigned either NF90_DOUBLE or NF90_FLOAT, depending on the user parameter) integer(I4B) :: ncid !! NetCDF ID for the output file - integer(I4B) :: dimids(2) !! Dimensions of the NetCDF file + integer(I4B) :: dimids(3) !! Dimensions of the NetCDF file integer(I4B) :: time_dimid !! NetCDF ID for the time dimension + integer(I4B) :: id_dimid !! NetCDF ID for the particle id dimension + integer(I4B) :: str_dimid !! NetCDF ID for the character string dimension integer(I4B) :: time_varid !! NetCDF ID for the time variable - integer(I4B) :: id_dimid !! NetCDF ID for the particle name dimension integer(I4B) :: id_varid !! NetCDF ID for the particle name variable integer(I4B) :: name_varid !! NetCDF ID for the semimajor axis variable integer(I4B) :: npl_varid !! NetCDF ID for the number of active massive bodies variable @@ -156,7 +157,7 @@ module swiftest_classes !******************************************************************************************************************************** !> A concrete lass for the central body in a Swiftest simulation type, abstract, extends(swiftest_base) :: swiftest_cb - character(len=STRMAX) :: name !! Non-unique name + character(len=NAMELEN) :: name !! Non-unique name integer(I4B) :: id = 0 !! External identifier (unique) real(DP) :: mass = 0.0_DP !! Central body mass (units MU) real(DP) :: Gmass = 0.0_DP !! Central mass gravitational term G * mass (units GU * MU) @@ -193,29 +194,29 @@ module swiftest_classes !> An abstract class for a generic collection of Swiftest bodies type, abstract, extends(swiftest_base) :: swiftest_body !! Superclass that defines the generic elements of a Swiftest particle - logical :: lfirst = .true. !! Run the current step as a first - integer(I4B) :: nbody = 0 !! Number of bodies - character(len=STRMAX), dimension(:), allocatable :: name !! Non-unique name - integer(I4B), dimension(:), allocatable :: id !! External identifier (unique) - integer(I4B), dimension(:), allocatable :: status !! An integrator-specific status indicator - logical, dimension(:), allocatable :: ldiscard !! Body should be discarded - logical, dimension(:), allocatable :: lmask !! Logical mask used to select a subset of bodies when performing certain operations (drift, kick, accel, etc.) - real(DP), dimension(:), allocatable :: mu !! G * (Mcb + [m]) - real(DP), dimension(:,:), allocatable :: xh !! Swiftestcentric position - real(DP), dimension(:,:), allocatable :: vh !! Swiftestcentric velocity - real(DP), dimension(:,:), allocatable :: xb !! Barycentric position - real(DP), dimension(:,:), allocatable :: vb !! Barycentric velocity - real(DP), dimension(:,:), allocatable :: ah !! Total heliocentric acceleration - real(DP), dimension(:,:), allocatable :: aobl !! Barycentric accelerations of bodies due to central body oblatenes - real(DP), dimension(:,:), allocatable :: atide !! Tanngential component of acceleration of bodies due to tides - real(DP), dimension(:,:), allocatable :: agr !! Acceleration due to post-Newtonian correction - real(DP), dimension(:), allocatable :: ir3h !! Inverse heliocentric radius term (1/rh**3) - real(DP), dimension(:), allocatable :: a !! Semimajor axis (pericentric distance for a parabolic orbit) - real(DP), dimension(:), allocatable :: e !! Eccentricity - real(DP), dimension(:), allocatable :: inc !! Inclination - real(DP), dimension(:), allocatable :: capom !! Longitude of ascending node - real(DP), dimension(:), allocatable :: omega !! Argument of pericenter - real(DP), dimension(:), allocatable :: capm !! Mean anomaly + logical :: lfirst = .true. !! Run the current step as a first + integer(I4B) :: nbody = 0 !! Number of bodies + character(len=NAMELEN), dimension(:), allocatable :: name !! Non-unique name + integer(I4B), dimension(:), allocatable :: id !! External identifier (unique) + integer(I4B), dimension(:), allocatable :: status !! An integrator-specific status indicator + logical, dimension(:), allocatable :: ldiscard !! Body should be discarded + logical, dimension(:), allocatable :: lmask !! Logical mask used to select a subset of bodies when performing certain operations (drift, kick, accel, etc.) + real(DP), dimension(:), allocatable :: mu !! G * (Mcb + [m]) + real(DP), dimension(:,:), allocatable :: xh !! Swiftestcentric position + real(DP), dimension(:,:), allocatable :: vh !! Swiftestcentric velocity + real(DP), dimension(:,:), allocatable :: xb !! Barycentric position + real(DP), dimension(:,:), allocatable :: vb !! Barycentric velocity + real(DP), dimension(:,:), allocatable :: ah !! Total heliocentric acceleration + real(DP), dimension(:,:), allocatable :: aobl !! Barycentric accelerations of bodies due to central body oblatenes + real(DP), dimension(:,:), allocatable :: atide !! Tanngential component of acceleration of bodies due to tides + real(DP), dimension(:,:), allocatable :: agr !! Acceleration due to post-Newtonian correction + real(DP), dimension(:), allocatable :: ir3h !! Inverse heliocentric radius term (1/rh**3) + real(DP), dimension(:), allocatable :: a !! Semimajor axis (pericentric distance for a parabolic orbit) + real(DP), dimension(:), allocatable :: e !! Eccentricity + real(DP), dimension(:), allocatable :: inc !! Inclination + real(DP), dimension(:), allocatable :: capom !! Longitude of ascending node + real(DP), dimension(:), allocatable :: omega !! Argument of pericenter + real(DP), dimension(:), allocatable :: capm !! Mean anomaly !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the !! component list, such as setup_body and util_spill contains diff --git a/src/modules/swiftest_globals.f90 b/src/modules/swiftest_globals.f90 index cf0c7248a..3df99a8d1 100644 --- a/src/modules/swiftest_globals.f90 +++ b/src/modules/swiftest_globals.f90 @@ -43,6 +43,7 @@ module swiftest_globals integer(I4B), parameter :: RINGMOONS = 9 integer(I4B), parameter :: STRMAX = 512 !! Maximum size of character strings + integer(I4B), parameter :: NAMELEN = 32 !! Maximum size of name strings character(*), parameter :: ASCII_TYPE = 'ASCII' !! Symbolic name for ASCII file type character(*), parameter :: REAL4_TYPE = 'REAL4' !! Symbolic name for binary file type REAL4 @@ -130,6 +131,7 @@ module swiftest_globals character(*), parameter :: NETCDF_OUTFILE = 'bin.nc' !! Default output file name character(*), parameter :: TIME_DIMNAME = "time" !! NetCDF name of the time dimension character(*), parameter :: ID_DIMNAME = "id" !! NetCDF name of the particle id dimension + character(*), parameter :: STR_DIMNAME = "str" !! NetCDF name of the particle id dimension character(*), parameter :: NAME_VARNAME = "name" !! NetCDF name of the particle name variable character(*), parameter :: NPL_VARNAME = "npl" !! NetCDF name of the number of active massive bodies variable character(*), parameter :: NTP_VARNAME = "ntp" !! NetCDF name of the number of active test particles variable diff --git a/src/netcdf/netcdf.f90 b/src/netcdf/netcdf.f90 index 2a3e09709..8234ad4c2 100644 --- a/src/netcdf/netcdf.f90 +++ b/src/netcdf/netcdf.f90 @@ -53,7 +53,8 @@ module subroutine netcdf_initialize_output(self, param) ! Define the NetCDF dimensions with particle name as the record dimension call check( nf90_def_dim(self%ncid, ID_DIMNAME, NF90_UNLIMITED, self%id_dimid) ) ! 'x' dimension call check( nf90_def_dim(self%ncid, TIME_DIMNAME, NF90_UNLIMITED, self%time_dimid) ) ! 'y' dimension - self%dimids = [self%time_dimid, self%id_dimid ] + call check( nf90_def_dim(self%ncid, STR_DIMNAME, NAMELEN, self%str_dimid) ) ! Dimension for string variables (aka character arrays) + self%dimids = [self%time_dimid, self%id_dimid, self%str_dimid] select case (param%out_type) case(NETCDF_FLOAT_TYPE) @@ -67,6 +68,7 @@ module subroutine netcdf_initialize_output(self, param) call check( nf90_def_var(self%ncid, ID_DIMNAME, NF90_INT, self%id_dimid, self%id_varid) ) call check( nf90_def_var(self%ncid, NPL_VARNAME, NF90_INT, self%time_dimid, self%npl_varid) ) call check( nf90_def_var(self%ncid, NTP_VARNAME, NF90_INT, self%time_dimid, self%ntp_varid) ) + call check( nf90_def_var(self%ncid, NAME_VARNAME, NF90_CHAR, [self%id_dimid, self%str_dimid], self%name_varid) ) if ((param%out_form == XV) .or. (param%out_form == XVEL)) then call check( nf90_def_var(self%ncid, XHX_VARNAME, self%out_type, self%dimids, self%xhx_varid) ) call check( nf90_def_var(self%ncid, XHY_VARNAME, self%out_type, self%dimids, self%xhy_varid) ) @@ -142,6 +144,7 @@ module subroutine netcdf_open(self, param) call check( nf90_inq_varid(self%ncid, ID_DIMNAME, self%id_varid)) call check( nf90_inq_varid(self%ncid, NPL_VARNAME, self%npl_varid)) call check( nf90_inq_varid(self%ncid, NTP_VARNAME, self%ntp_varid)) + call check( nf90_inq_varid(self%ncid, NAME_VARNAME, self%name_varid)) !call check( nf90_inq_varid(self%ncid, NAME_VARNAME, self%name_varid)) if ((param%out_form == XV) .or. (param%out_form == XVEL)) then @@ -161,10 +164,10 @@ module subroutine netcdf_open(self, param) call check( nf90_inq_varid(self%ncid, CAPM_VARNAME, self%capm_varid)) end if call check( nf90_inq_varid(self%ncid, GMASS_VARNAME, self%Gmass_varid)) + if (param%lclose) call check( nf90_inq_varid(self%ncid, RADIUS_VARNAME, self%radius_varid)) if (param%lrhill_present) call check( nf90_inq_varid(self%ncid, RHILL_VARNAME, self%rhill_varid)) if (param%lrotation) then - call check( nf90_inq_varid(self%ncid, RADIUS_VARNAME, self%radius_varid)) call check( nf90_inq_varid(self%ncid, IP1_VARNAME, self%Ip1_varid)) call check( nf90_inq_varid(self%ncid, IP2_VARNAME, self%Ip2_varid)) call check( nf90_inq_varid(self%ncid, IP3_VARNAME, self%Ip3_varid)) @@ -211,8 +214,9 @@ module subroutine netcdf_write_frame_base(self, iu, param) class(netcdf_parameters), intent(inout) :: iu !! Parameters used to identify a particular NetCDF dataset class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals - integer(I4B) :: i, j, id, tslot + integer(I4B) :: i, j, id, tslot, strlen, idslot integer(I4B), dimension(:), allocatable :: ind + character(len=:), allocatable :: name !! Open the netCDF file @@ -227,66 +231,70 @@ module subroutine netcdf_write_frame_base(self, iu, param) do i = 1, n j = ind(i) - id = self%id(j) - - call check( nf90_put_var(iu%ncid, iu%id_varid, id, start=[id]) ) - !call check( nf90_put_var(iu%ncid, iu%name_varid, trim(adjustl(self%name(j))), start=[tslot, id]) ) + idslot = self%id(j) + 1 + call check( nf90_put_var(iu%ncid, iu%id_varid, id, start=[idslot]) ) + name = trim(adjustl(self%name(j))) + strlen = len(name) + call check( nf90_put_var(iu%ncid, iu%name_varid, name, start=[id, 1], count=[1, strlen]) ) if ((param%out_form == XV) .or. (param%out_form == XVEL)) then - call check( nf90_put_var(iu%ncid, iu%xhx_varid, self%xh(1, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%xhy_varid, self%xh(2, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%xhz_varid, self%xh(3, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%vhx_varid, self%vh(1, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%vhy_varid, self%vh(2, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%vhz_varid, self%vh(3, j), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%xhx_varid, self%xh(1, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%xhy_varid, self%xh(2, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%xhz_varid, self%xh(3, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%vhx_varid, self%vh(1, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%vhy_varid, self%vh(2, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%vhz_varid, self%vh(3, j), start=[tslot, idslot]) ) end if if ((param%out_form == EL) .or. (param%out_form == XVEL)) then - call check( nf90_put_var(iu%ncid, iu%a_varid, self%a(j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%e_varid, self%e(j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%inc_varid, self%inc(j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%capom_varid, self%capom(j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%omega_varid, self%omega(j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%capm_varid, self%capm(j), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%a_varid, self%a(j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%e_varid, self%e(j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%inc_varid, self%inc(j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%capom_varid, self%capom(j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%omega_varid, self%omega(j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%capm_varid, self%capm(j), start=[tslot, idslot]) ) end if select type(pl => self) class is (swiftest_pl) ! Additional output if the passed polymorphic object is a massive body - call check( nf90_put_var(iu%ncid, iu%Gmass_varid, pl%Gmass(j), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%Gmass_varid, pl%Gmass(j), start=[tslot, idslot]) ) if (param%lrhill_present) then - call check( nf90_put_var(iu%ncid, iu%rhill_varid, pl%rhill(j), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%rhill_varid, pl%rhill(j), start=[tslot, idslot]) ) end if if (param%lclose) then - call check( nf90_put_var(iu%ncid, iu%radius_varid, pl%radius(j), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%radius_varid, pl%radius(j), start=[tslot, idslot]) ) end if if (param%lrotation) then - call check( nf90_put_var(iu%ncid, iu%Ip1_varid, pl%Ip(1, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%Ip2_varid, pl%Ip(2, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%Ip3_varid, pl%Ip(3, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%rotx_varid, pl%rot(1, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%roty_varid, pl%rot(2, j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%rotz_varid, pl%rot(3, j), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%Ip1_varid, pl%Ip(1, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%Ip2_varid, pl%Ip(2, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%Ip3_varid, pl%Ip(3, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%rotx_varid, pl%rot(1, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%roty_varid, pl%rot(2, j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%rotz_varid, pl%rot(3, j), start=[tslot, idslot]) ) end if if (param%ltides) then - call check( nf90_put_var(iu%ncid, iu%k2_varid, pl%k2(j), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%Q_varid, pl%Q(j), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%k2_varid, pl%k2(j), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%Q_varid, pl%Q(j), start=[tslot, idslot]) ) end if end select end do end associate class is (swiftest_cb) id = self%id - call check( nf90_put_var(iu%ncid, iu%id_varid, id, start=[id]) ) - call check( nf90_put_var(iu%ncid, iu%Gmass_varid, self%Gmass, start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%radius_varid, self%radius, start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%id_varid, id, start=[idslot]) ) + name = trim(adjustl(self%name)) + strlen = len(name) + call check( nf90_put_var(iu%ncid, iu%name_varid, name, start=[id, 1], count=[1, strlen]) ) + call check( nf90_put_var(iu%ncid, iu%Gmass_varid, self%Gmass, start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%radius_varid, self%radius, start=[tslot, idslot]) ) if (param%lrotation) then - call check( nf90_put_var(iu%ncid, iu%Ip1_varid, self%Ip(1), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%Ip2_varid, self%Ip(2), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%Ip3_varid, self%Ip(3), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%rotx_varid, self%rot(1), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%roty_varid, self%rot(2), start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%rotz_varid, self%rot(3), start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%Ip1_varid, self%Ip(1), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%Ip2_varid, self%Ip(2), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%Ip3_varid, self%Ip(3), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%rotx_varid, self%rot(1), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%roty_varid, self%rot(2), start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%rotz_varid, self%rot(3), start=[tslot, idslot]) ) end if if (param%ltides) then - call check( nf90_put_var(iu%ncid, iu%k2_varid, self%k2, start=[tslot, id]) ) - call check( nf90_put_var(iu%ncid, iu%Q_varid, self%Q, start=[tslot, id]) ) + call check( nf90_put_var(iu%ncid, iu%k2_varid, self%k2, start=[tslot, idslot]) ) + call check( nf90_put_var(iu%ncid, iu%Q_varid, self%Q, start=[tslot, idslot]) ) end if end select