diff --git a/.github/workflows/clean_artifacts.yml b/.github/workflows/clean_artifacts.yml new file mode 100644 index 0000000..a1b3d0d --- /dev/null +++ b/.github/workflows/clean_artifacts.yml @@ -0,0 +1,12 @@ +name: 'Delete old artifacts' +on: [push] + + +jobs: + delete-artifacts: + runs-on: ubuntu-latest + steps: + - uses: kolpav/purge-artifacts-action@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + expire-in: 0 # Setting this to 0 will delete all artifacts diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml new file mode 100644 index 0000000..82cd67e --- /dev/null +++ b/.github/workflows/make.yml @@ -0,0 +1,194 @@ +name: make + +on: + push: + branches: [master] +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + create_release: + runs-on: ubuntu-latest + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + steps: + - name: GitHub Tag + id: tag_release + # You may pin to the exact commit or the version. + # uses: mathieudutour/github-tag-action@1bab3ab0712cafa42b54c512453487b89bb06504 + uses: mathieudutour/github-tag-action@v5 + with: + # Required for permission to tag the repo. + github_token: ${{ secrets.GITHUB_TOKEN }} + # Which type of bump to use when none explicitly provided (default: `patch`). + # default_bump: # optional, default is patch + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ steps.tag_release.outputs.new_tag }} + release_name: Release ${{ steps.tag_release.outputs.new_tag }} + draft: false + prerelease: false + + manylinux-build: + needs: [create_release] + runs-on: ubuntu-latest + strategy: + matrix: + include: + - name: manylinux2010-gfortran + compiler: gfortran + container: quay.io/pypa/manylinux2010_x86_64 + - name: manylinux2010-f2c + compiler: f2c + container: quay.io/pypa/manylinux2010_x86_64 + + container: ${{ matrix.container }} + steps: + # We need to install packages first, because the checkout needs gcc already + - run: yum install -y gcc-gfortran f2c cmake autoconf automake libtool + - run: git clone https://github.com/AWehrhahn/SMElib . + - name: Replace Makefile + if: matrix.compiler == 'f2c' + run: rm Makefile.am && mv Makefile_f2c.am Makefile.am + - name: Run F2C + if: matrix.compiler == 'f2c' + run: f2c -w -a -C++ -Nn1604 -Nq1200 -dsrc/eos/ src/eos/*.f & f2c -w -a -C++ -dsrc/sme/ src/sme/*.f + - run: ./bootstrap && ./configure --prefix=$PWD + - run: make install + - run: zip -r ${{ matrix.name }} lib share + + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps + asset_path: ./${{ matrix.name }}.zip + asset_name: ${{ matrix.name }}.zip + asset_content_type: application/zip + + build: + needs: create_release + strategy: + fail-fast: false + matrix: + include: + - name: ubuntu-gfortran + runs_on: ubuntu-latest + packages: gfortran + outputs: lib share + - name: ubuntu-f2c + runs_on: ubuntu-latest + packages: f2c + outputs: lib share + - name: windows-gfortran + runs_on: ubuntu-latest + packages: gfortran mingw-w64 mingw-w64-tools mingw-w64-common gfortran-mingw-w64 gfortran-mingw-w64-x86-64 gcc-mingw-w64 gcc-mingw-w64-x86-64 g++-mingw-w64 g++-mingw-w64-x86-64 + cxx: x86_64-w64-mingw32-gcc + f77: x86_64-w64-mingw32-gfortran + config_flags: --build=x86_64-pc-linux-gnu --host=x86_64-w64-mingw32 + outputs: bin share +# F2C doesn't work for Windows, use gfortran instead +# will figure this out when possible +# - name: windows-f2c +# runs_on: ubuntu-latest +# packages: f2c mingw-w64 mingw-w64-tools mingw-w64-common gcc-mingw-w64 gcc-mingw-w64-x86-64 g++-mingw-w64 g++-mingw-w64-x86-64 +# cxx: x86_64-w64-mingw32-gcc +# config_flags: --build=x86_64-pc-linux-gnu --host=x86_64-w64-mingw32 +# outputs: bin share + - name: macos-gfortran + runs_on: macos-latest + packages: automake libtool + cxx: gcc-9 + f77: gfortran-9 + outputs: lib share + - name: macos-f2c + runs_on: macos-latest + taps: FranklinChen/tap + packages: automake libtool + cxx: gcc-9 + outputs: lib share + + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ${{ matrix.runs_on }} + + steps: + - uses: actions/checkout@v2 + + - name: Install packages + if: matrix.runs_on == 'ubuntu-latest' + run: sudo apt-get install -y ${{ matrix.packages }} + + - name: Install packages + if: matrix.runs_on == 'macos-latest' + run: brew tap ${{ matrix.taps }} && brew install ${{ matrix.packages }} + + - name: Install F2C + if: matrix.name == 'macos-f2c' + run: brew install --verbose --HEAD franklinchen/tap/f2c + + - name: Run F2C + if: matrix.name == 'ubuntu-f2c' || matrix.name == 'windows-f2c' || matrix.name == 'macos-f2c' + run: f2c -w -a -C++ -Nn1604 -Nq1200 -dsrc/eos/ src/eos/*.f & f2c -w -a -C++ -dsrc/sme/ src/sme/*.f + + - name: Replace Makefile.am + if: matrix.name == 'ubuntu-f2c' || matrix.name == 'windows-f2c' + run: rm Makefile.am && mv Makefile_f2c.am Makefile.am + + - name: Replace Makefile.am + if: matrix.name == 'macos-f2c' + run: rm Makefile.am && mv Makefile_mac.am Makefile.am + + - name: Copy F2C headers + if: matrix.name == 'windows-f2c' + run: cp /usr/include/f2c.h src/eos/ & cp /usr/include/f2c.h src/sme/ + + - name: Run Bootstrap and Configure + env: + CXX: ${{ matrix.cxx }} + F77: ${{ matrix.f77 }} + run: ./bootstrap && ./configure --prefix=$PWD ${{ matrix.config_flags }} + + - name: Install + env: + CXX: ${{ matrix.cxx }} + F77: ${{ matrix.f77 }} + run: make install + + - name: Zip data # This would actually build your project, using zip for an example artifact + run: zip -r ${{ matrix.name }} ${{ matrix.outputs }} + + - name: Archive compiled library + uses: actions/upload-artifact@v2 + with: + name: library + path: ${{ matrix.name }}.zip + + - name: Prepare Test Environment + if: matrix.name != 'windows-gfortran' && matrix.name != 'windows-f2c' + run: pip3 install -r test/requirements.txt + + - name: Test Library + if: matrix.name != 'windows-gfortran' && matrix.name != 'windows-f2c' + run: python3 -m pytest + + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps + asset_path: ./${{ matrix.name }}.zip + asset_name: ${{ matrix.name }}.zip + asset_content_type: application/zip diff --git a/.gitignore b/.gitignore index f9a85bc..6b1f92d 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,9 @@ src/sme/.deps/ build/ test/__pycache__/ dev/ +kp_q_spln.c +src/eos/eos_eqns.c +src/eos/eos_math_special.c +src/eos/eos.c +src/sme/hlinop.c +src/sme/hlinprof.c diff --git a/.travis.yml b/.travis.yml index 65a5157..825e782 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,27 @@ jobs: - python3-pip cache: - pip + - os: linux + name: f2c + env: + - TARGET=linux-f2c + - OUTPUT_DIRS="lib share" + addons: + apt: + packages: + - g++ + - f2c + - make + - python3.5 + - python3-venv + - python3-pip + cache: + - pip + before_install: + - f2c -w -a -C++ -Nn1604 -Nq1200 -dsrc/eos/ src/eos/*.f + - f2c -w -a -c++ -dsrc/sme/ src/sme/*.f + - rm makefile.am + - mv makefile_f2c.am makefile.am - os: linux name: manylinux2010 services: diff --git a/Makefile_f2c.am b/Makefile_f2c.am new file mode 100644 index 0000000..6456513 --- /dev/null +++ b/Makefile_f2c.am @@ -0,0 +1,41 @@ +AUTOMAKE_OPTIONS = foreign + +ACLOCAL_AMFLAGS = -I m4 + +lib_LTLIBRARIES = libsme.la +libsme_la_SOURCES = \ + src/sme/platform.h \ + src/sme/sme_synth_faster.cpp \ + src/eos/eos.c \ + src/eos/eos_eqns.c \ + src/eos/eos_math_special.c \ + src/eos/kp_q_spln.c \ + src/sme/hlinop.c \ + src/sme/hlinprof.c +libsme_la_LDFLAGS = -fPIC -version-info 5:22:0 -shared -no-undefined +libsme_la_CPPFLAGS = -fPIC -shared +libsme_la_LIBADD = -lc -l:libf2c.a -lm -lstdc++ + +dist_pkgdata_DATA = src/data/bpo_self.grid.INTEL \ + src/data/Fe1_Bautista2017.dat.INTEL \ + src/data/NH_Stancil2018.dat.INTEL \ + src/data/stehle_long.dat.INTEL \ + src/data/vcsbalmer.dat + +BUILT_SOURCES = src/sme/platform.h old_link + +CLEANFILES = src/sme/platform.h + +PLATFORM = @TARGET@ +MACHINE = @TARGET_CPU@ +BITS = 64 +SHL_EXT = "$(PLATFORM).$(MACHINE).$(BITS)" + +DATA_DIR = @datadir@/libsme/ + +src/sme/platform.h: + echo '#define PLATFORM "$(PLATFORM)"' > src/sme/platform.h + echo '#define DATA_DIR "$(DATA_DIR)"' >> src/sme/platform.h + +old_link: libsme.la + $(MKDIR_P) $(@OUTPUT_DIR@) && cd $(@OUTPUT_DIR@) && $(LN_S) -f libsme@EXTENSION@ sme_synth.so.$(SHL_EXT) diff --git a/Makefile_mac.am b/Makefile_mac.am new file mode 100644 index 0000000..c7cf472 --- /dev/null +++ b/Makefile_mac.am @@ -0,0 +1,42 @@ +AUTOMAKE_OPTIONS = foreign + +ACLOCAL_AMFLAGS = -I m4 + +lib_LTLIBRARIES = libsme.la +libsme_la_SOURCES = \ + src/sme/platform.h \ + src/sme/sme_synth_faster.cpp \ + src/eos/eos.c \ + src/eos/eos_eqns.c \ + src/eos/eos_math_special.c \ + src/eos/kp_q_spln.c \ + src/sme/hlinop.c \ + src/sme/hlinprof.c +libsme_la_LDFLAGS = -fPIC -version-info 5:22:0 -shared -no-undefined +libsme_la_CPPFLAGS = -fPIC -shared +# Here we assume that f2c has been installed using homebrew, since the automatic detection seems to fail... +libsme_la_LIBADD = -lc /usr/local/Cellar/f2c/HEAD/lib/libf2c.a -lm -lstdc++ + +dist_pkgdata_DATA = src/data/bpo_self.grid.INTEL \ + src/data/Fe1_Bautista2017.dat.INTEL \ + src/data/NH_Stancil2018.dat.INTEL \ + src/data/stehle_long.dat.INTEL \ + src/data/vcsbalmer.dat + +BUILT_SOURCES = src/sme/platform.h old_link + +CLEANFILES = src/sme/platform.h + +PLATFORM = @TARGET@ +MACHINE = @TARGET_CPU@ +BITS = 64 +SHL_EXT = "$(PLATFORM).$(MACHINE).$(BITS)" + +DATA_DIR = @datadir@/libsme/ + +src/sme/platform.h: + echo '#define PLATFORM "$(PLATFORM)"' > src/sme/platform.h + echo '#define DATA_DIR "$(DATA_DIR)"' >> src/sme/platform.h + +old_link: libsme.la + $(MKDIR_P) $(@OUTPUT_DIR@) && cd $(@OUTPUT_DIR@) && $(LN_S) -f libsme@EXTENSION@ sme_synth.so.$(SHL_EXT) \ No newline at end of file diff --git a/README.md b/README.md index 3faffec..7baa6b3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Build Status](https://travis-ci.com/AWehrhahn/SMElib.svg?branch=master)](https://travis-ci.com/AWehrhahn/SMElib) - +![CMake](https://github.com/AWehrhahn/SMElib/workflows/CMake/badge.svg) # SMElib Spectroscopy Made Easy Source Library @@ -11,7 +11,9 @@ spectrum of a star with a model spectrum. Since its initial release in ## Download You can find compiled versions of the library for Unix, Mac OS, and Windows under [Releases](https://github.com/AWehrhahn/SMElib/releases). -Note that depending on your system you might have to install libgfortran (version 3) as well. + +There are two versions for each OS. The gfortran version uses gfortran to compile the Fortran code, while the [F2C](https://www.netlib.org/f2c/) version first converts the Fortran code to C++ code. The difference between these two are that f2c does not require libgfortran, but gives slightly numerical differences. It also appears to run faster in preliminary tests. +Note that depending on your system you might have to install libgfortran as well. ## Notes - SMElib requires libgfortran on most OSs to be installed. The exact version, depends on the version of SMELib that you are installing. If PySME fails to load the library try adding that libgfortran file in the same directory. diff --git a/src/sme/hlinop.f b/src/sme/hlinop.f index 4400894..b161e90 100644 --- a/src/sme/hlinop.f +++ b/src/sme/hlinop.f @@ -221,6 +221,18 @@ REAL FUNCTION HPROFL(N,M,WAVE,WAVEH,T,XNE,H1FRC,HE1FRC,DOPPH) REAL*8 CLIGHT LOGICAL LYMANALF SAVE + +C Define some constants + PARAMETER (PI = 3.14159265359, SQRTPI = 1.77245385) + PARAMETER (CLIGHT = 2.9979258E18) + PARAMETER (CLIGHTCM = 2.99792458E10) + +C +C Most model atmosphere codes include Rayleigh scattering by H atoms +C elsewhere, eg. quantum mechanical calculations. This parameter cuts +C the Lyman alpha natural absorption at this chosen point. +C + PARAMETER (RAYLCUT = 1240.D0) ! in Angstroms C C Einstein A-value sums for H lines C @@ -328,6 +340,7 @@ REAL FUNCTION HPROFL(N,M,WAVE,WAVEH,T,XNE,H1FRC,HE1FRC,DOPPH) C LYMAN ALPHA QUASI H2 PROFILE C DELTA WAVENO = -22000+200*(N-1) N=1,91 -4000 C + DATA LYMANH2/ 1 -13.43, -13.32, -13.21, -13.10, -12.98, -12.86, -12.79, -12.72, 2 -12.65, -12.58, -12.51, -12.47, -12.45, -12.45, -12.48, -12.51, @@ -341,16 +354,7 @@ REAL FUNCTION HPROFL(N,M,WAVE,WAVEH,T,XNE,H1FRC,HE1FRC,DOPPH) A -12.87, -12.86, -12.85, -12.84, -12.83, -12.81, -12.80, -12.79, 1 -12.78, -12.76, -12.74, -12.72, -12.70, -12.68, -12.65, -12.62, 2 -12.59, -12.56, -12.53/ -C - PARAMETER (PI = 3.14159265359, SQRTPI = 1.77245385) - PARAMETER (CLIGHT = 2.9979258E18) - PARAMETER (CLIGHTCM = 2.99792458E10) -C -C Most model atmosphere codes include Rayleigh scattering by H atoms -C elsewhere, eg. quantum mechanical calculations. This parameter cuts -C the Lyman alpha natural absorption at this chosen point. -C - PARAMETER (RAYLCUT = 1240.D0) ! in Angstroms + C C Data for self-broadening from calculations of Barklem, Piskunov and C O'Mara (2000, A&A 363, 1091). @@ -704,6 +708,12 @@ FUNCTION STARK1(N,M,WAVE,WAVEH,T,XNE) DIMENSION Y1WTM(2,2),XKNMTB(4,3) LOGICAL LYMANALF SAVE + +C + PARAMETER (CLIGHT = 2.9979258E18) + PARAMETER (PI = 3.14159265359, SQRTPI = 1.77245385) + PARAMETER (H = 6.62618E-27) !Planck in cgs + PARAMETER (K = 1.38066E-16) !Boltzmann in cgs C C Knm constants as defined by Griem (1960, ApJ 132, 883) for the long C range Holtsmark profile (due to ions only). Lyman and Balmer series @@ -715,11 +725,7 @@ FUNCTION STARK1(N,M,WAVE,WAVEH,T,XNE) C DATA Y1WTM/1.E18, 1.E17, 1.E16, 1.E14/ DATA N1/0/, M1/0/ -C - PARAMETER (CLIGHT = 2.9979258E18) - PARAMETER (PI = 3.14159265359, SQRTPI = 1.77245385) - PARAMETER (H = 6.62618E-27) !Planck in cgs - PARAMETER (K = 1.38066E-16) !Boltzmann in cgs + C C Variables depending on conditions C diff --git a/src/sme/hlinprof.f b/src/sme/hlinprof.f index 8cb19d2..c48e61c 100644 --- a/src/sme/hlinprof.f +++ b/src/sme/hlinprof.f @@ -83,14 +83,17 @@ SUBROUTINE HLINPROF(WAVE,WAVE0,TEMP,XXNE,NLOW,NUP, LOGICAL FIRST INCLUDE 'DATA.FILES' C + PARAMETER (C = 2.997925E+18, PI = 3.14159265) + COMMON /HSWITCH/ISTARK,ISELF,ICONV,IHE + SAVE FIRST C DATA FIRST/.TRUE./ - PARAMETER (C = 2.997925E+18, PI = 3.14159265) + C C Set the switches here C - COMMON /HSWITCH/ISTARK,ISELF,ICONV,IHE + ISTARK = 1 ISELF = 2 ICONV = 1 @@ -314,10 +317,12 @@ SUBROUTINE STEHLE(HFILE,WAVE,WAVE0,TEMP,XXNE,NLOW,NUP,HLIN, C Open file and process errors C IF(BYTE_SWAP.EQ.0) THEN - OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD') + OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD') ELSE - OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD', - * CONVERT='LITTLE_ENDIAN') + WRITE(*,*) 'ERROR: STEHLE File in Big Endian format' + STOP + ! OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD', + ! * CONVERT='LITTLE_ENDIAN') END IF IF(IERR.NE.0) THEN WRITE(*,*) 'ERROR: STEHLE did not find Hydrogen line file' @@ -566,12 +571,11 @@ SUBROUTINE STEHLE(HFILE,WAVE,WAVE0,TEMP,XXNE,NLOW,NUP,HLIN, C 9 I=INDEX(HFILE,' ')-1 IF(I.LE.0) I=LEN(HFILE) - WRITE(*,*) 'ERROR reading binary file '//HFILE(1:I)//' in HTABLE' + WRITE(*,*) 'ERROR reading binary file in HTABLE' STOP 10 I=INDEX(HFILE,' ')-1 IF(I.LE.0) I=LEN(HFILE) - WRITE(*,*) 'EOF found while reading binary file '//HFILE(1:I)// - * ' in HTABLE' + WRITE(*,*) 'EOF found while reading binary file in HTABLE' STOP END @@ -613,10 +617,11 @@ SUBROUTINE HGRID(HFILE,WAVE,WAVE0,TEMP,NHYD,NLOW,NUP,HLIN, CHARACTER HFILE*(*) SAVE T,NH,F0,MALPHA,MSPROF,PALPHA,PSPROF,PNALPHA,MNALPHA, * NPROFS,NTEMP,NNH,NLINE,FIRST,LINDEX - DATA FIRST/.TRUE./,LINDEX/10000*0/ - PARAMETER (SQRTPI=1.77245385) + PARAMETER (SQRTPI=1.77245385) REAL*8 DEXP10,X DEXP10(X)=EXP(2.30258509299405D0*X) + DATA FIRST/.TRUE./,LINDEX/10000*0/ + C C Read in the table (this is done only once) C @@ -626,10 +631,12 @@ SUBROUTINE HGRID(HFILE,WAVE,WAVE0,TEMP,NHYD,NLOW,NUP,HLIN, C Open file and process errors C IF(BYTE_SWAP.EQ.0) THEN - OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD') + OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD') ELSE - OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD', - * CONVERT='LITTLE_ENDIAN') + WRITE(*,*) 'ERROR: HGRID File in Big Endian' + STOP + ! OPEN(1,file=HFILE,IOSTAT=IERR,FORM='UNFORMATTED',STATUS='OLD', + ! * CONVERT='LITTLE_ENDIAN') END IF IF(IERR.NE.0) THEN WRITE(*,*) 'ERROR: HGRID did not find Hydrogen line file' @@ -994,12 +1001,11 @@ SUBROUTINE HGRID(HFILE,WAVE,WAVE0,TEMP,NHYD,NLOW,NUP,HLIN, C 9 I=INDEX(HFILE,' ')-1 IF(I.LE.0) I=LEN(HFILE) - WRITE(*,*) 'ERROR reading binary file '//HFILE(1:I)//' in HGRID' + WRITE(*,*) 'ERROR reading binary file in HGRID' STOP 10 I=INDEX(HFILE,' ')-1 IF(I.LE.0) I=LEN(HFILE) - WRITE(*,*) 'EOF found while reading binary file '//HFILE(1:I)// - * ' in HGRID' + WRITE(*,*) 'EOF found while reading binary file in HGRID' STOP END diff --git a/travis/build.sh b/travis/build.sh index 2fc1a29..4d2b92c 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -1,7 +1,12 @@ #!/bin/bash # Install dependencies -yum install -y gcc-gfortran cmake autoconf automake libtool +yum install -y gcc f2c cmake autoconf automake libtool + +f2c -w -a -C++ -Nn1604 -Nq1200 -dsrc/eos/ src/eos/*.f +f2c -w -a -c++ -dsrc/sme/ src/sme/*.f +rm makefile.am +mv makefile_f2c.am makefile.am ./bootstrap ./configure --prefix=$PWD