diff --git a/.gitignore b/.gitignore index 6ef3005..90f0989 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,11 @@ libfvcom.a *.mod *.o *.f90 + +# Compiled libraries and install directory +libs/install/ +libs/julian/ +libs/metis/build/ + +# Project documentation (user-specific) +CLAUDE.md diff --git a/docs/BUILD_MACOS.md b/docs/BUILD_MACOS.md new file mode 100644 index 0000000..a41b7bb --- /dev/null +++ b/docs/BUILD_MACOS.md @@ -0,0 +1,152 @@ +# Building FVCOM on macOS (Apple Silicon / Intel) + +This guide describes how to build FVCOM on macOS using gfortran and OpenMPI. + +## Prerequisites + +Install required dependencies via Homebrew: + +```bash +brew install gcc open-mpi netcdf netcdf-fortran hdf5 metis +``` + +## Configuration (make.inc) + +A macOS configuration template is provided at `src/make-mac.inc`. To use it: + +```bash +cd src +cp make-mac.inc make.inc +``` + +Then edit `make.inc` with your specific paths: + +**OR** manually edit `src/make.inc` with the following changes: + +### 1. Set paths + +```makefile +TOPDIR = /path/to/FVCOM/src +INSTALLDIR = /path/to/FVCOM/libs/install +``` + +### 2. Enable LOCAL INSTALL + +```makefile +LIBDIR = -L$(INSTALLDIR)/lib +INCDIR = -I$(INSTALLDIR)/include +``` + +### 3. Configure NetCDF (Homebrew paths) + +```makefile +IOLIBS = -L/opt/homebrew/lib -lnetcdff -lnetcdf +IOINCS = -I/opt/homebrew/include +``` + +### 4. Configure METIS (Homebrew paths) + +```makefile +FLAG_411 = -DMETIS_5 +PARLIB = +PARTINCS = -I/opt/homebrew/include +PARTLIBS = -L/opt/homebrew/lib -lmetis +``` + +### 5. Use gfortran/OpenMPI compiler + +Comment out the Intel compiler section and add: + +```makefile +CPP = /usr/bin/cpp +COMPFLAG = -DGFORTRAN +CC = mpicc +CXX = mpicxx +CFLAGS = -O3 +FC = mpif90 +DEBFLGS = +OPT = -O3 -ffree-line-length-none +CLIB = +``` + +## Building the Julian Library + +The Julian library requires a fix for Fortran name mangling on macOS with gfortran. + +### Fix fortran.h + +Edit `libs/julian/fortran.h` and remove the `__APPLE__` special case for `FORTRAN_NAME`: + +**Before:** +```c +#ifdef __APPLE__ +#define FORTRAN_NAME(name) name + +#else + +#ifdef __STDC__ +#define FORTRAN_NAME(name) name##_ +... +``` + +**After:** +```c +#ifdef __STDC__ +#define FORTRAN_NAME(name) name##_ + +#else +#define FORTRAN_NAME(name) name/**/_ + +#endif +#endif +``` + +This ensures gfortran's expected trailing underscore convention is used. + +### Build and install Julian + +```bash +cd libs/julian +make clean +make libjulian + +# Install to libs/install +mkdir -p ../install/lib ../install/include +cp libjulian.a ../install/lib/ +cp fjulian.inc ../install/include/ +``` + +## Building FVCOM + +```bash +cd src + +# Clean previous build +make clean + +# Manually compile partition.c (workaround for makefile issue) +mpicc -c -O3 -I/opt/homebrew/include partition.c + +# Build FVCOM +make +``` + +## Known Issues + +### 1. partition.c not compiled automatically + +The makefile's `ifdef FLAG_411` check occurs before `make.inc` is included, so `partition.c` may not be compiled. Compile it manually as shown above. + +### 2. Parallel make race condition + +Using `make -j` may cause race conditions with module dependencies. If you encounter "Cannot open module file" errors, run `make` without the `-j` flag. + +## Verification + +Test the build: + +```bash +./fvcom --help +``` + +You should see the FVCOM help message with available options. diff --git a/src/make-mac.inc b/src/make-mac.inc new file mode 100644 index 0000000..569df5e --- /dev/null +++ b/src/make-mac.inc @@ -0,0 +1,188 @@ +#/===========================================================================/ +# macOS Configuration Template for FVCOM +# +# This is a reference configuration for building FVCOM on macOS (Apple Silicon +# and Intel) using gfortran and OpenMPI from Homebrew. +# +# To use this template: +# 1. Copy this file: cp make-mac.inc make.inc +# 2. Edit the TOPDIR and INSTALLDIR paths below +# 3. Adjust library paths if your Homebrew installation differs +# 4. Run: make clean && make +# +# See docs/BUILD_MACOS.md for detailed build instructions +#/===========================================================================/ + +#========== TOPDIR ======================================================== +# TOPDIR is the directory in which this make file and the fvcom source reside +# !!! CHANGE THIS TO YOUR ACTUAL PATH !!! + + TOPDIR = /path/to/FVCOM/src + +#========== INSTALLDIR ===================================================== +# INSTALLDIR is where you installed the Julian library +# !!! CHANGE THIS TO YOUR ACTUAL PATH !!! + + INSTALLDIR = /path/to/FVCOM/libs/install + +#=========================================================================== +# PREPROCESSOR OPTIONS FOR CPP + DEF_FLAGS = -P -traditional + +#=========================================================================== +# MEDM ENVIRONMENT - Use environmental variables if set +colon=: +empty= +dashI= $(empty) -I +dashL= $(empty) -L + +ifeq ($(origin LIBPATH), environment) + LIBDIR = -L$(subst $(colon),$(dashL),$(LIBPATH)) +endif +ifeq ($(origin INCLUDEPATH), environment) + INCDIR = -I$(subst $(colon),$(dashI),$(INCLUDEPATH)) +endif + +#=========================================================================== +# LOCAL INSTALL - Point to your local Julian library installation + LIBDIR = -L$(INSTALLDIR)/lib + INCDIR = -I$(INSTALLDIR)/include + +#-------------------------------------------------------------------------- +# STANDARD LIBRARIES FOR DATA AND TIME + DTLIBS = -ljulian + DTINCS = + +#-------------------------------------------------------------------------- +# NETCDF - Homebrew paths for Apple Silicon +# For Intel Mac, change /opt/homebrew to /usr/local +#-------------------------------------------------------------------------- + FLAG_USE_NETCDF4 = -DUSE_NETCDF4 +# FLAG_USE_COMPRESSION = -DUSE_COMPRESSION + IOLIBS = -L/opt/homebrew/lib -lnetcdff -lnetcdf + IOINCS = -I/opt/homebrew/include + +#========================================================================== +# MODEL OPTIONS - Typical configuration for development/testing +#========================================================================== + +# PRECISION - Double precision with single precision output + FLAG_1 = -DDOUBLE_PRECISION -DSINGLE_OUTPUT + +# SPHERICAL COORDINATES + FLAG_2 = -DSPHERICAL + +# WET/DRY TREATMENT + FLAG_3 = -DWET_DRY + +# MPI PARALLELIZATION with METIS 5 + FLAG_4 = -DMULTIPROCESSOR + FLAG_411 = -DMETIS_5 + PARLIB = + PARTINCS = -I/opt/homebrew/include + PARTLIBS = -L/opt/homebrew/lib -lmetis + +# WATER QUALITY MODEL (uncomment to enable) +# FLAG_5 = -DWATER_QUALITY + +# PROJECTION (uncomment to enable) +# FLAG_6 = -DPROJ +# PROJLIBS = -lfproj4 -lproj -lm +# PROJINCS = + +# DATA ASSIMILATION (uncomment to enable, requires PETSc) +# FLAG_7 = -DDATA_ASSIM +# include ${PETSC_DIR}/bmake/common/variables +# OILIB = -lmkl_lapack -lmkl_em64t -lguide -lpthread + +# ADVECTION LIMITER - Choose ONE (REQUIRED) + FLAG_8 = -DLIMITED_NO +# FLAG_8 = -DLIMITED_1 +# FLAG_8 = -DLIMITED_2 + +# SEMI-IMPLICIT (uncomment to enable, requires PETSc) +# FLAG_9 = -DSEMI_IMPLICIT +# include ${PETSC_DIR}/bmake/common/variables + +# SOLID BOUNDARY TREATMENT - Choose ONE (REQUIRED) + FLAG_10 = -DGCN +# FLAG_10 = -DGCY1 +# FLAG_10 = -DGCY2 + +# GOTM TURBULENCE MODEL (uncomment to enable) +# FLAG_11 = -DGOTM +# GOTMLIB = -L../GOTM_source -lturbulence -lutil +# GOTMINCS = -I../GOTM_source + +# EQUILIBRIUM TIDE (uncomment to enable) +# FLAG_12 = -DEQUI_TIDE + +# ATMOSPHERIC TIDE (uncomment to enable) +# FLAG_13 = -DATMO_TIDE + +# RIVER DISTRIBUTION (uncomment for old-style floating point) +# FLAG_14 = -DRIVER_FLOAT + +# TVD (Total Variational Diminishing) - Recommended for better accuracy + FLAG_44 = -DTVD + +# MPDATA SCHEME + FLAG_15 = -DMPDATA + +# ADDITIONAL OPTIONS (uncomment as needed) +# FLAG_16 = -DLAG_PARTICLE +# FLAG_17 = -DDYE_RELEASE +# FLAG_18 = -DTWO_D_MODEL +# FLAG_19 = -DICE +# FLAG_20 = -DICE_EMBEDDING +# FLAG_21 = -DSEDIMENT +# FLAG_22 = -DSED_CSTMS +# FLAG_23 = -DOFFLINE_BIOLOGY +# FLAG_24 = -DOFFLINE_SEDIMENT +# FLAG_25 = -DVISIT +# FLAG_26 = -DVIS_OMVIZ +# FLAG_27 = -DBIO_CALC +# FLAG_28 = -DPROBES +# FLAG_29 = -DSTATION_TIMESERIES +# FLAG_30 = -DBALANCE_2D +# FLAG_31 = -DENKF +# FLAG_32 = -DENKF_DETAILS +# FLAG_33 = -DRRKASSIM +# FLAG_34 = -DTIGHT_COUPLING +# FLAG_35 = -DONE_D_TIDEBC +# FLAG_36 = -DBALANCE_2D_VIA_FVCOM +# FLAG_37 = -DBALANCE_3D_VIA_OCEAN +# FLAG_38 = -DDTI_RESET_S +# FLAG_39 = -DDTI_RESET_M +# FLAG_40 = -DNESTING +# FLAG_41 = -DMEAN_FLOW_RIVER +# FLAG_42 = -DPLBC +# FLAG_43 = -DDAM_BREAK +# FLAG_45 = -DFLUID_MUD +# FLAG_46 = -DOUT_STATION +# FLAG_47 = -DOUT_SPARSE +# FLAG_48 = -DDOUBLE_ECHO +# FLAG_49 = -DBOUNDSCHK +# FLAG_50 = -DESMF_NESTING +# FLAG_51 = -DFLOCMOD +# FLAG_52 = -DTPXO_TIDE +# FLAG_53 = -DMLD_RHO +# FLAG_54 = -DVEGETATION +# FLAG_55 = -DSEDIMENT_HEATING + +#-------------------------------------------------------------------------- +# gfortran/OpenMPI Compiler Configuration (Homebrew) +#-------------------------------------------------------------------------- + CPP = /usr/bin/cpp + COMPFLAG = -DGFORTRAN + CC = mpicc + CXX = mpicxx + CFLAGS = -O3 + FC = mpif90 + DEBFLGS = + OPT = -O3 -ffree-line-length-none + CLIB = + +#========================================================================== +# END OF USER CONFIGURATION +#========================================================================== diff --git a/src/swancom5.F b/src/swancom5.F index 0b858a9..0dabdb2 100644 --- a/src/swancom5.F +++ b/src/swancom5.F @@ -118,19 +118,23 @@ SUBROUTINE SWAPAR1(I,IS,ID,DEP2,KWAVEL,CGOL) IMPLICIT NONE ! INTEGER :: IC,IS,ID,I,INDX - REAL :: NN(1:MSC), ND(1:MSC) + REAL :: NN(1:MSC), ND(1:MSC) REAL :: DEP2(MT),KWAVEL,CGOL - REAL :: DEPLOC,SPCSIGL + REAL :: DEPLOC + ! Local arrays for KSCIP1 interface (gfortran compatibility) + REAL :: SPCSIGL(1),KWAVEL_ARR(1),CGOL_ARR(1),NNL(1),NDL(1) DEPLOC = (DEP2(NV(I,1))+DEP2(NV(I,2))+DEP2(NV(I,3)))/3.0 IF(DEPLOC <= DEPMIN)THEN ! *** depth is negative *** - KWAVEL = -1. - CGOL = 0. + KWAVEL = -1. + CGOL = 0. ELSE ! *** call KSCIP1 to compute KWAVE and CGO *** - SPCSIGL = SPCSIG(IS) - CALL KSCIP1(1,SPCSIGL,DEPLOC,KWAVEL,CGOL,NN,ND) + SPCSIGL(1) = SPCSIG(IS) + CALL KSCIP1(1,SPCSIGL,DEPLOC,KWAVEL_ARR,CGOL_ARR,NNL,NDL) + KWAVEL = KWAVEL_ARR(1) + CGOL = CGOL_ARR(1) END IF RETURN