Xportfrac with USGS28

We don’t think your method will work, plus it’s more complicated than just merging the GRIDCRO2D with the LUFRAC_CRO. We have posted a tool in lufrac_cro_for_afdust.zip that should help. We will post the file to this folder momentarily: https://gaftp.epa.gov/Air/emismod/2016/v2/ancillary_data/

The file contains an executable (lugrid.exe.atm) and a script to run it (lugrid.csh). In the script, you just need to change LUFRAC (point to the LUFRAC_CRO file) and INGRID (point to the GRIDCRO2D) file, and you will get a GRIDCRO2D file which contains the LUFRAC variables that the afdust tool uses. Hopefully this will help you generate a file that will work.

3 Likes

Thanks a lot. Meantime I managed to use the m3tools to generate the needed GRIDCRO file and it worked in the xportfrac generation as well. I am putting everything together to test it in smoke now.

Thanks again for all the help and guidance. you guys are amazing !!

Hi Alison,

there is an error to use this.

./lugrid.exe.atm: error while loading shared libraries: libnetcdf.so.11: cannot open shared object file: No such file or directory

Is there other version of this executable file.

Thank you

Do you have a compiled version of netcdf?

Thank you for the quick reply.
I set module load netcdf/4.7.4-intel2020 in my bash file.

So are you saying this was like that already and you still got the error?

yes.
This error is similar to that when I use 2016beta/afdust_xportfrac/gen_afdust_tfrac. Based on the suggestion from post Xportfrac error
I used that from 2016v2, no that error.
When I want to combine LUFRAC and GRIDCRO2D file, use lugrid.exe.atm, this error happens.

We have updated this zip file to include the source code and some compilation instructions:

https://gaftp.epa.gov/Air/emismod/2016/v2/ancillary_data/lufrac_cro_for_afdust.zip

Please let us know if you are unable to compile the source code into a usable executable.

Hi Alison,

I am unable to compile the source code. Do I have to use my compiler to install ioapi to keep consistent for netcdf and ioapi? I just used ioapi from NEI package directly.

Thank you.

From the I/O API Availability/Download/Installation of the EDSS/Models-3 I/O API document:

In general, you are best off if you can build your whole modeling system (libnetcdf.a, libpvm3.a, libioapi.a, and your model(s) CMAQ, SMOKE, etc. with a common compiler set and common set of compile-flags.

This is especially true for the Fortran-compiled parts of the system, by the way. And the further recommendation is that you use static linking (with libnetcdf.a, libnetcdff.a instead of libnetcdf.so, libnetcdff.so), especially because there is no other way of ensuring that the ompiler and compiler-flags are compatible all the way across the build.

*-- Carlie J. Coats, Jr., Ph.D. *
I/O API Author/Maintainer

Jeff,

Thoughts on this? Carlie sent a response after this one I’m forwarding.

Alison

Hi Alison,

Thank you for the information. I may try that later.
I installed mcip4.4 and got GRIDCRO2D with LUFRAC.

Thanks.

I had a number of issues with the provided lufrac program. I’ve had a look, and drafted what should in the long run be a better version, together with I/O API compatible Makefile. Note that these are drafts; I don’t have input files to use to test them. Also, this forum-software will probably mess up the tabs in the Makefile ;-(

For whatever reason, this reply-panel is not giving me an “attach” option, so here are these file,
in-line:


----------------------  lufrac.f90  ------------------------------------------------------------------------
PROGRAM lugrid

    USE M3UTILIO

    !!***************************************************************
    !! Version "$Id: lugrid.f90 242 2023-04-10 14:59:56Z coats $"
    !! add lufrac info from LUFRAC_CRO file with INGRID data to combined OUTGRID.
    !! this PROGRAM assumes:
    !!  REVISION  HISTORY:
    !! 1. only one variable on input LUFRAC file called LUFRAC with units=percent and var_desc="fractional land use"
    !! 2. each timestep in LUFRAC is the same data as each other timestep's data, so only one timestep is read for inputs.
    !! 3. only one level input for the ingrid file
    !! Revision   4/2023 by CJC:  Many I/O  API / Standards compliance items.
    !!***************************************************************

    USE M3UTILIO

    IMPLICIT NONE

    CHARACTER*16, PARAMETER :: PNAME = 'LUGRID'

    !! atmos intel17.0.3 netcdf4.4.1 ioapi3.2:

    !!17 ifort -fPIC -check -traceback -extend_source -zero -O3 -mp1 -o lugrid.exe.atm lugrid.f -L/home/local-rhel7/apps/netcdf-4.4.1/intel-17.0/lib -lnetcdf -lnetcdff -L/home/local-rhel7/apps/ioapi-3.2/intel-17.0/lib -lioapi -module /home/local-rhel7/apps/ioapi-3.2/intel-17.0/Linux2_x86_64ifort

    real,    ALLOCATABLE :: lufrac(:, :)  ! x, y lufrac of LUFRAC_CRO 1st timestep, layer-n going to lufrac_n in GRIDCRO2D.

    character*16 :: luvar(MXVARS3), ingridvar(MXVARS3), outgridvar(MXVARS3)
    character*16 :: luuni(MXVARS3), ingriduni(MXVARS3), outgriduni(MXVARS3)
    character*80 :: ludes(MXVARS3), ingriddes(MXVARS3), outgriddes(MXVARS3)

    integer         k, n, nfrac, nvars3, LOGUNIT, ISTAT
    character*16    vname
    CHARACTER*256   MESG
    LOGICAL     ::  EFLAG = .FALSE.

    !!........  LUFRAC_CRO file parameters (must match INGRID parameters)

    integer  FTYPE1
    integer  NTHIK1
    integer  NCOLS1
    integer  NROWS1
    integer  NLAYS1
    integer  GDTYP1
    real*8   P_ALP1
    real*8   P_BET1
    real*8   P_GAM1
    real*8   XCENT1
    real*8   YCENT1
    real*8   XORIG1
    real*8   YORIG1
    real*8   XCELL1
    real*8   YCELL1

    integer  NVARS2

    LOGUNIT = INIT3( )

    !!........  open "LUFRAC" input file and get its dimensions and variable attributes

    IF ( .not. OPEN3( 'LUFRAC', FSREAD3, PNAME ) ) THEN
        CALL M3EXIT( PNAME, 0,0, 'OPEN3( LUFRAC,... ) failure', 2 )
    ELSE IF ( .not. DESC3( 'LUFRAC' ) ) THEN
        CALL M3EXIT( PNAME, 0,0, 'DESC3( LUFRAC,... ) failure', 2 )
    ELSE IF ( NVARS3D .NE. 1 ) THEN
        CALL M3EXIT( PNAME, 0,0, 'LUFRAC input must have just one variable', 2 )
    ELSE IF ( TSTEP3D .NE. 0 ) THEN
        CALL M3EXIT( PNAME, 0,0, 'LUFRAC input must be time independent', 2 )
    ELSE IF ( vtype3d(1) .NE. M3REAL ) THEN
        CALL M3EXIT( PNAME, 0,0, 'LUFRAC input must be of type REAL', 2 )
    ELSE            !! save lufrac input file description
        FTYPE1 = FTYPE3D
        NTHIK1 = NTHIK3D
        NCOLS1 = NCOLS3D
        NROWS1 = NROWS3D
        NLAYS1 = NLAYS3D
        GDTYP1 = GDTYP3D
        P_ALP1 = P_ALP3D
        P_BET1 = P_BET3D
        P_GAM1 = P_GAM3D
        XCENT1 = XCENT3D
        YCENT1 = YCENT3D
        XORIG1 = XORIG3D
        YORIG1 = YORIG3D
        XCELL1 = XCELL3D
        YCELL1 = YCELL3D
        NFRAC  = NLAYS3D

        luvar(1) = vname3d(1)
        luuni(1) = units3d(1)
        ludes(1) = vdesc3d(1)
    END IF

    !!........  open ingrid values input file and get its dimensions and variable attributes

    IF ( .not. OPEN3( 'INGRID', FSREAD3, PNAME ) ) THEN
        CALL M3EXIT( PNAME, 0,0, 'OPEN3( INGRID,... ) failure', 2 )
    ELSE IF ( .not. DESC3( 'INGRID' ) ) THEN
        CALL M3EXIT( PNAME, 0,0, 'DESC3( INGRID,... ) failure', 2 )
   ELSE IF ( .NOT.FILCHK3( 'INGRID', FTYPE1, NCOLS1, NROWS1, NLAYS1, NTHIK1 ) ) THEN
        CALL M3EXIT( PNAME, 0,0, 'Dimension mismatch:  "LUFRAC" vs "INGRID"', 2 )
   ELSE IF ( .NOT.GRDCHK3( 'INGRID',                                    &
                           P_ALP1, P_BET1, P_GAM1, XCENT1, YCENT1,      &
                           XORIG1, YORIG1, XCELL1, YCELL1,              &
                           NLAYS3D, VGTYP3D, VGTOP3D, VGLVS3D ) ) THEN
        CALL M3EXIT( PNAME, 0,0, 'Grid parameter mismatch:  "LUFRAC" vs "INGRID"', 2 )
    ELSE IF ( TSTEP3D .NE. 0 ) THEN
        CALL M3EXIT( PNAME, 0,0, 'INGRID input must be time independent', 2 )
    ELSE            !! save lufrac input file description
        NVARS2 = NVARS3D

        ingridvar(1:nvars2) = vname3d(1:nvars2)
        ingriduni(1:nvars2) = units3d(1:nvars2)
        ingriddes(1:nvars2) = vdesc3d(1:nvars2)

        DO n = 1,nvars2
            IF ( vtype3d(n).NE.M3REAL ) THEN
                MESG = 'INGRID:  variable "'//TRIM( vname3d(n) )//'" must be of type REAL'
                CALL M3EXIT( PNAME, 0,0, MESG, 2 )
            END IF
        END DO

    END IF

    !!........  create output arrays

    ALLOCATE ( lufrac(ncols1,nrows1), STAT = ISTAT )
    IF ( ISTAT .NE. 0 ) THEN
        WRITE( MESG, '( A, I10)' ) 'Buffer allocation failed:  STAT=', ISTAT
        CALL M3EXIT( PNAME, 0, 0, MESG, 2 )
    END IF

    nvars3 = nvars2 + nfrac  ! ingrid + lufrac

    outgridvar(1:nvars2) = ingridvar(1:nvars2)
    outgriduni(1:nvars2) = ingriduni(1:nvars2)
    outgriddes(1:nvars2) = ingriddes(1:nvars2)

    outgriduni(nvars2+1:nvars3) = luuni(1)  ! assumes just one lufrac file var input
    outgriddes(nvars2+1:nvars3) = ludes(1)

    DO n = 1, nfrac
        k = nvars2 + n
        write(outgridvar(k), '(A,i2)')  'LUFRAC_', n ! should range from 0-99
    END DO

    nvars3d = nvars3
    vname3d(1:nvars3) = outgridvar(1:nvars3)
    units3d(1:nvars3) = outgriduni(1:nvars3)
    vdesc3d(1:nvars3) = outgriddes(1:nvars3)
    vtype3d(1:nvars3) = M3REAL

    IF ( .not. OPEN3( 'OUTGRID', FSUNKN3, PNAME ) ) THEN
        CALL M3EXIT( PNAME, 0,0, 'OPEN3( OUTGRID,... ) failure', 2 )
    END IF

    DO k = 1, nvars2
        vname = ingridvar(k)
        IF ( .not.  read3('INGRID' , ingridvar(k), 1,0,0, lufrac) ) THEN
            EFLAG = .TRUE.
        ELSE IF ( .not. write3('OUTGRID', ingridvar(k),   0,0, lufrac) ) THEN
            EFLAG = .TRUE.
        END IF
    END DO

    DO n = 1, nfrac
        k = nvars2 + n
        IF ( .not. read3('LUFRAC', luvar(1), n,0,0, lufrac) ) THEN
            EFLAG = .TRUE.
        ELSE IF ( .not. write3('OUTGRID', outgridvar(k), 0,0, lufrac) ) THEN
            EFLAG = .TRUE.
        END IF
    END DO


    IF ( EFLAG ) THEN
        MESG  = 'Failure in program'
        ISTAT = 2
    ELSE
        MESG  = 'Success in program'
        ISTAT = 0
    END IF

    CALL M3EXIT( PNAME, 0, 0, MESG, ISTAT )

END PROGRAM lugrid
----------------------  Makefile  ------------------------------------------------------------------------
#
#.........................................................................
# Version "$Id: Makefile 236 2023-04-10 19:40:25Z coats $"
#.........................................................................
#  Environment Variables:
#       BIN     machine/OS/compiler/mode type. Shows up as suffix
#               for "Makeinclude.${BIN}" to determine compilation
#               flags, and in ${OBJDIR} and $(INSTALL) to determine
#               binary directories
#       INSTALL installation-directory root, used for "make install"
#.........................................................................
#  Directories:
#       $(SRCDIR)   is the source directory for this program
#       ${IOAPI}   is the root directory for the I/O API library source
#       ${OBJDIR}   is the current machine/compiler/flag-specific
#                   build-directory
#.........................................................................
#
#       ---------------     Definitions:   -------------------------

.SUFFIXES: .m4 .c .F .f .f90 .F90

SRCDIR = ${HOME}/tmp/lugrid
IOAPI  = ${HOME}/ioapi-3.2

BLDDIR = ${SRCDIR}/${BIN}
IOSRC  = ${IOAPI}/ioapi
IOLIB  = ${IOAPI}/${BIN}

# Architecture dependent stuff
# Assumes FC is an f90

include ${IOSRC}/Makeinclude.${BIN}

FFLAGS = ${MODI}$(IOLIB)  $(ARCHFLAGS) $(PARFLAGS) $(FOPTFLAGS) $(ARCHFLAGS)

LDFLAGS = -I$(IODIR) $(DEFINEFLAGS) $(ARCHFLAGS)

#  Incompatibility between netCDF versions before / after v4.1.1:
#  For netCDF v4 and later, you may also need the extra libraries
#  given by netCDF commands
#
#          nc-config --libs
#          nf-config --libs
#
#  Cygwin libraries need "-lnetcdff.dll -lnetcdf.dll" below
#
 LIBS = -L${IOLIB} -lioapi -lnetcdff -lnetcdf  $(OMPLIBS) $(ARCHLIB) $(ARCHLIBS)
#LIBS = -L${IOLIB} -lioapi -lnetcdf  $(OMPLIBS) $(ARCHLIB) $(ARCHLIBS)
#LIBS = -L${IOLIB} -lioapi `nf-config --libs` `nc-config --libs` $(OMPLIBS) $(ARCHLIB) $(ARCHLIBS)

VPATH = ${OBJDIR}:${IOLIB}

f90SRC = lugrid.f90

OBJ = $(f90SRC:.f90=.o)

EXE = lugrid

all: $(EXE)

clean:
	cd ${OBJDIR}; rm $(EXE) $(OBJ)

install: 
	echo "Installing M3TOOLS in ${INSTDIR}"
	cd ${OBJDIR}; cp $(EXE) $(INSTDIR)

rmexe:
	cd ${OBJDIR}; rm ${EXE}

relink:
	make BIN=${BIN} -i rmexe ; make BIN=${BIN} all

bins:
	make BIN=Linux2_x86_64
	make BIN=Linux2_x86_64sun
	make BIN=Linux2_x86_64ifort
	make BIN=Linux2_x86_64dbg
	make BIN=Linux2_x86_64sundbg
	make BIN=Linux2_x86_64ifortdbg

binclean:
	make -i BIN=Linux2_x86_64          clean
	make -i BIN=Linux2_x86_64sun       clean
	make -i BIN=Linux2_x86_64ifort     clean
	make -i BIN=Linux2_x86_64dbg       clean
	make -i BIN=Linux2_x86_64sundbg    clean
	make -i BIN=Linux2_x86_64ifortdbg  clean


binrelink:
	make BIN=Linux2_x86_64         relink
	make BIN=Linux2_x86_64sun      relink
	make BIN=Linux2_x86_64ifort    relink
	make BIN=Linux2_x86_64dbg      relink
	make BIN=Linux2_x86_64sundbg   relink
	make BIN=Linux2_x86_64ifortdbg relink


#      -----------------------   RULES:   -------------------------

%.o : %.mod        #  Disable "gmake"s obnoxious implicit Modula-2 rule !!

.f90.o:
	if [ ! -d ${BLDDIR} ]; then mkdir -p ${BLDDIR}; fi
	cd ${BLDDIR}; $(FC) $(FFLAGS) -c $(SRCDIR)/$<

#  ---------------------------  Dependencies:  --------------------

lugrid.o : m3utilio.mod


#  ---------------------------  $(EXE) Program builds:  -----------------


lugrid:  lugrid.o
	cd ${BLDDIR}; $(FC) ${LFLAGS} $^ ${LIBS} -o $@

---------------------- README ------------------------------------------------------------------------

ON A NEW VERSION OF PROGRAM "LUGRID"
    -- Carlie J. Coats, Jr., Ph.D.

There were a number of things wrong with the old program-version
“lugrid.f”:

  1. I/O API based programs should use M3EXIT for program termination.
    They should not use “STOP”.

  2. Grid consistency checks depend upon exact match of all the (REAL*8)
    grid parameters. This has been shown repeatedly to be incorrect.
    One needs instead to use checks which allow for reasonable round-off
    error; ideally, the checks should use standard library routines
    FILCHK3() and GRDCHK3().

  3. The author does not understand the OPEN3 I/O APU call. In EVERY
    instance, the third argument is incorrect.

  4. Error-checking is inadequate, particularly as regards ALLOCATE.

  5. The author does not understand the concept of a time independent
    file (see Dates and Time Conventions), and
    introduces much unneeded complexity as a result.

  6. There are a number of errors regarding arrays and array-sections,
    and how they should appear in argument-lists. Fortunately, many
    compilers “do the right thing” anyway (this is NOT true of recent
    "gfortran"s, however!)

  7. The compile instructions are messy, at best, and it is difficult
    to ensure that they are compatible with the libraries used.

  8. There is a lot of unnecessary complexity and redundancy.

It might be good for the author to read both the relevant conding
standards document (at M3IO Software Development Standards),
and possibly “Optimizing Environmental Models for Microprocessor Based
Systems”, an updated version for a 2002 seminar at EPA ORD, found at
Environmental Model Optimization.

IN THIS TAR-BALL:

README,txt -- this file

lugrid.f90 -- new version of the program, with the above corrected,
and in (current) free-format (".f90") Fortran source form.  Note
that in spite of muc additional error-checking, it is only about
3/4 the size of its predecessor...

Makefile  -- to build the program, compatibly with a standard
I/O API installation (in multiple versions, compatible with 
I/O API library versions).

TO BUILD THE PROGRAM:

Save these files to a new directory *lugrid* (I did it under my *$HOME/tmp*...)

Edit the "Makefile" so that make-variables
    `IOAPI`  is the "root" of the current I/O API installation
    `SRCDIR` is the source directory of the program
    Optionally, `BLDDIR` is the build-directory

"cd" to the program's source-directory

"make"  will build the program in `BLDDIR (=$SRCDIR/$BIN` unless
you changed it).

Carlie,

Thanks for putting together the better code! Offline we talked about one other additional edit that is needed for the following FILCHK3 call line:

ELSE IF ( .NOT.FILCHK3( ‘INGRID’, FTYPE1, NCOLS1, NROWS1, NLAYS1, NTHIK1 ) ) THEN
CALL M3EXIT( PNAME, 0,0, ‘Dimension mismatch: “LUFRAC” vs “INGRID”’, 2 )

should be:

ELSE IF ( .NOT.FILCHK3( ‘INGRID’, FTYPE1, NCOLS1, NROWS1, 1, NTHIK1 ) ) THEN
CALL M3EXIT( PNAME, 0,0, ‘Dimension mismatch: “LUFRAC” vs “INGRID”’, 2 )

correct?

Jeff

Yes, that is correct… – Carlie

I put Carlie’s code with the FILCHK3 update and his instructions in a zipped file and put it in the same directory as the older lugrid code here:

https://gaftp.epa.gov/Air/emismod/2016/v2/ancillary_data/lufrac_cro_for_afdust.code_update.041823.zip

I am trying to generate Xportfrac for a new domain. The WRF data we obtained seems to have used 28 land use categories. Therefore, I used USGS 24 land-use type, #28 as lake, and #25-#27 are unassigned. I added these to both gridcro2d_lu_types and captureclass_fractions files. i learn all domain also discussion to other people but i have no solution.

[quote=“VijaySonwane, post:37, topic:3173, full:true”]
I am trying to generate Xportfrac for a new domain. The WRF data we obtained seems to have used 28 land use categories. Therefore, I used USGS 24 land-use type, #28 as lake, and #25-#27 are unassigned. I added these to both gridcro2d_lu_types and captureclass_fractions files. i learn all domain also discussion to other people but i have no solution.
[/quote] Sodium Hypo Chlorite

Are tiy having a problem generating an XPORTFRAC (which could be unrelated to the land use types), or do you need guidance on how to update the input files for types 25-28. If you do not make any changes to the gridcro2d_lu_types and captureclass_fractions files, does it work?

Also, have you read the earlier comments in that thread about the LUFRAC variables have you accounted for that (i.e. run lugrid.exe to add LUFRAC variables to the GRIDCRO2D)?