doc/install: palm_installer

File palm_installer, 53.8 KB (added by knoop, 7 years ago)
Line 
1#!/usr/bin/env bash
2#------------------------------------------------------------------------------#
3# This file is part of PALM.
4#
5# PALM is free software: you can redistribute it and/or modify it under the
6# terms of the GNU General Public License as published by the Free Software
7# Foundation, either version 3 of the License, or (at your option) any later
8# version.
9#
10# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# PALM. If not, see <http://www.gnu.org/licenses/>.
16#
17# Copyright 1997-2015  Leibniz Universitaet Hannover
18#------------------------------------------------------------------------------#
19# palm_installer - an automatic installation scipt for PALM
20#------------------------------------------------------------------------------#
21
22# script version
23installer_version="v0.3.22"
24
25# log all output of this script in a file
26this_script=$(basename $0)
27logfile_all="$(pwd)/palm_installer.log"
28rm -f ${logfile_all}
29exec >  >(tee -ia ${logfile_all})
30exec 2> >(tee -ia ${logfile_all} >&2)
31
32# opens a terminal in case started with a double click
33if [ ! -t 0 ]; then
34   if type konsole > /dev/null; then
35      konsole --noclose -e $@
36   elif type terminal > /dev/null; then
37      xterm -hold -e $@
38   fi
39   exit 0
40fi
41
42get_number_of_cpu_cores() {
43   {
44      # OSX
45      n=$(sysctl -n machdep.cpu.core_count 2> /dev/null)
46   } || {
47      # Linux
48      n=$(grep -c ^processor /proc/cpuinfo 2> /dev/null)
49   } || {
50      # fallback
51      if ! [[ $n =~ ^-?[0-9]+$ ]]; then
52         n=2
53      fi
54   }
55   echo $n
56}
57
58install_prefix=${HOME}/palm/current_version
59shell_profile=${HOME}/.bashrc
60program_name="PALM"
61NUM_PROC=$(get_number_of_cpu_cores)
62palm_base_url="https://palm.muk.uni-hannover.de"
63palm_svn_url="${palm_base_url}/svn/palm/trunk"
64number_of_cols=70
65logfile_test="palm_test.log"
66
67palm_installer_url="http://palm.muk.uni-hannover.de/trac/raw-attachment/wiki/doc/install/automatic/palm_installer"
68newest_installer_version=$(wget -qO- ${palm_installer_url} | \
69                           sed -n '/installer_version=\"v.*/p' | \
70                           sed  's/installer_version=\"\(v.*\)\"/\1/g')
71
72palm_installer_update() {
73   hrule
74   if [[ "${newest_installer_version}" == "" ]]; then
75      printf "| \e[1;33m%-${number_of_cols}s\e[0m |\n" "Please make sure you are using the latest ${program_name} installer version."
76   elif [[ "${newest_installer_version}" == "${installer_version}" ]]; then
77      printf "| \e[1;32m%-${number_of_cols}s\e[0m |\n" "This automatic installer is up to date."
78   else
79      printf "\e[1;33m%-${number_of_cols}s\e[0m\n" "This automatic installer is outdated!"
80      palm_read_yn "Do you wish to update to ${newest_installer_version}?" "RESPONSE_INSTALLER_UPDATE"
81      if [[ "$RESPONSE_INSTALLER_UPDATE" == "y" ]]; then
82         if wget ${palm_installer_url} --output-document=${this_script} &> /dev/null ; then
83            printf "\e[1;32m%-${number_of_cols}s\e[0m\n" "Successfully updated to ${newest_installer_version}"
84            bash ${this_script}
85            exit 0
86         else
87            printf "\e[1;33m%-${number_of_cols}s\e[0m\n"  "Update failed. Please manually download the newest installer from."
88            printf "\e[1;33m%-${number_of_cols}s\e[0m\n"  "   https://palm.muk.uni-hannover.de/trac/wiki/doc/install#automatic"
89            palm_installer_abort_message
90         fi
91      else
92         printf "\e[1;33m%-${number_of_cols}s\e[0m\n"  "WARNING: You are using and outdated ${program_name} installer."
93         printf "\e[1;33m%-${number_of_cols}s\e[0m\n"  "         You will not get any support in case something goes wrong."
94      fi
95   fi
96}
97
98palm_installer_check_software_all() {
99   hrule
100   printf "%s\n" "Checking general software requirements..."
101   palm_installer_check_software_required "a Fortran compiler" ifort ftn gfortran mpif90
102   palm_installer_check_software_required "MPI" mpiexec mpirun aprun srun
103   palm_installer_check_software_optional "svn" "${program_name} has to be downloaded manually" svn
104   palm_installer_check_software_required "ksh" ksh
105   palm_installer_check_software_required "make" make
106   palm_installer_check_software_required "cmake" cmake
107   palm_installer_check_software_optional "qmake" "The GUI will not be available" qmake
108   if [[ "${required_software_available}" == "false" ]]; then
109      hrule
110      printf "| \e[1;31m%-${number_of_cols}s\e[0m |\n" "Please provide missing software and try again!"
111      palm_installer_abort_message
112   fi
113   if [[ "${optional_software_available}" == "false" ]]; then
114      printf "\e[1;33m%s\e[0m\n" "Some optional software is missing."
115      palm_read_yn "Do you wish to continue anyways?" "RESPONSE_CONTINUE"
116      hrule
117      if [[ "$RESPONSE_CONTINUE" == "y" ]]; then
118         printf "| \e[1;33m%-${number_of_cols}s\e[0m |\n"  "Some optional software is missing. Continue anyways..."
119      else
120         printf "| \e[1;31m%-${number_of_cols}s\e[0m |\n" "Please provide missing software and try again!"
121         palm_installer_abort_message
122      fi
123   else
124      hrule
125      printf "| \e[1;32m%-${number_of_cols}s\e[0m |\n"  "All required software found. Lets continue..."
126   fi
127}
128
129palm_installer_check_software() {
130   local software_found="false"
131   for current_software in ${@}; do
132      if command -v ${current_software} > /dev/null; then
133         local software_found="true"
134         local found_software="${found_software} ${current_software}"
135      fi
136   done
137   if [[ "${software_found}" == "false" ]]; then
138      return 1
139   else
140      echo "${found_software}"
141      return 0
142   fi
143   
144}
145
146palm_installer_check_software_required() {
147   local description=${1}
148   shift
149   printf "%s %-25s " "-- Looking for" "${description}..."
150   if palm_installer_check_software ${@} > /dev/null; then
151      printf "\e[1;32mfound\e[0m$(palm_installer_check_software ${@})"
152   else
153      printf "\e[1;31mnot found!\e[0m"
154      required_software_available="false"
155   fi
156   printf "\n"
157}
158
159palm_installer_check_software_optional() {
160   local description=${1}
161   shift
162   local feature=${1}
163   shift
164   printf "%s %-25s " "-- Looking for" "${description} (optional)..."
165   if palm_installer_check_software ${@} > /dev/null; then
166      printf "\e[1;32mfound\e[0m$(palm_installer_check_software ${@})"
167   else
168      printf "\e[1;33mnot found!\e[0m (${feature})"
169      optional_software_available="false"
170   fi
171   printf "\n"
172}
173
174# clean any old build and promt the user for all required info for installation
175palm_installer_init() {
176   hrule
177   printf "\n"
178   printf "The default installation directory is \"${install_prefix}\".\n"
179   palm_read_yn "Do you wish to install ${program_name} in the default directory?" "RESPONSE_PREFIX"
180   if [[ "$RESPONSE_PREFIX" != "y" ]]; then
181      read -p "-- Please enter a new installation directory: " CUSTOM_PREFIX
182      local input_dir=$(eval echo $CUSTOM_PREFIX)
183      local tmp=""
184      while ! readlink -f $input_dir > /dev/null; do
185         tmp="/$(basename $input_dir)${tmp}"
186         input_dir=$(dirname $input_dir)
187      done
188      install_prefix="$(readlink -f $input_dir)${tmp}"
189   fi
190   trunk_dir=${install_prefix}/trunk
191   source_dir=${install_prefix}/.installer.tmp
192   build_dir=${source_dir}/build
193   printf "%s \"\e[1;32m${install_prefix}\e[0m\"\n" "-- ${program_name} will be installed in:"
194   printf "\n"
195   
196   AVAILABLE_FORTRAN_COMPILER=$(palm_installer_check_software ifort ftn gfortran mpif90)
197   CUSTOM_FORTRAN_COMPILER=$(echo ${AVAILABLE_FORTRAN_COMPILER} | awk '{print $1;}')
198   printf "%s\n" "Available Fortran compilers on this computer:${AVAILABLE_FORTRAN_COMPILER}"
199   printf "%s \"\e[1;32m${CUSTOM_FORTRAN_COMPILER}\e[0m\".\n" "-- The default Fortran compiler for this installation is"
200   palm_read_yn "Do you wish to use the default Fortran compiler?" "RESPONSE_COMPILER"
201   if [[ "$RESPONSE_COMPILER" != "y" ]]; then
202      read -p "-- Please enter your prefered Fortran compiler: " CUSTOM_FORTRAN_COMPILER
203      while ! command -v ${CUSTOM_FORTRAN_COMPILER} > /dev/null; do
204         printf "%s \e[1;31mnot found!\e[0m\n" "-- \"${CUSTOM_FORTRAN_COMPILER}\""
205         read -p "Please try again: " CUSTOM_FORTRAN_COMPILER
206      done
207   fi
208   printf "%s \"\e[1;32m${CUSTOM_FORTRAN_COMPILER}\e[0m\" will be used.\n" "-- The Fortran compiler"
209   printf "\n"
210
211   printf "%s\n" "This installer can try to find your NetCDF libraries automatically."
212   palm_read_yn "Do you wish to use the automatic NetCDF library detection?" "RESPONSE_NETCDF"
213   if [[ "$RESPONSE_NETCDF" != "y" ]]; then
214      read -p "-- Please enter the netCDF C root path: " NETCDF_C_ROOT
215      read -p "-- Please enter the netCDF Fortran root path: " NETCDF_FORTRAN_ROOT
216      printf "%s \e[1;33mdisabled\e[0m.\n" "-- Automatic NetCDF library detection is"
217   else
218      printf "%s \e[1;32menabled\e[0m.\n" "-- Automatic NetCDF library detection is"
219   fi
220   printf "\n"
221
222   if [[ -d ${trunk_dir} ]] && [[ "$(svn status ${trunk_dir})" == ""  ]]; then
223      local existing_revision=$(palm_svn_local_revision)
224   fi
225
226   if [[ "${existing_revision}" != ""  ]]; then
227      printf "%s\n" "A working copy of ${program_name} (revision: ${existing_revision}) was found..."
228      palm_read_yn "Do you wish to update ${program_name}?" "RESPONSE_SVN"
229   else
230      printf "%s\n" "No working copy of ${program_name} was found so far..."
231      palm_read_yn "Do you wish to download ${program_name} via Subversion?" "RESPONSE_SVN"
232   fi
233   
234   if [[ "$RESPONSE_SVN" == "y" ]]; then
235      SVN_USER=$(palm_svn_get_username)
236      printf "%s \e[1;32m$SVN_USER\e[0m \n" "-- Your ${program_name} username is:"
237      palm_svn_check_remote
238      newest_revision=$(palm_svn_newest_revision)
239      printf "%s\n" "-- By default the latest ${program_name} revision (revision: ${newest_revision}) will be aquired."
240      palm_read_yn "Do you wish to get the latest ${program_name} revision?" "RESPONSE_REVISION"
241      if [[ "$RESPONSE_REVISION" != "y" ]]; then
242         read -p "-- Please enter the desired ${program_name} revision (1 to ${newest_revision}): " CUSTOM_REVISION
243         while [[ ${CUSTOM_REVISION} -gt ${newest_revision} ]] || [[ ${CUSTOM_REVISION} -lt 1 ]]; do
244            printf "%s \e[1;31mnot a valid ${program_name} revision!\e[0m " "--"
245            read -p "Please choose a value between 1 and ${newest_revision}: " CUSTOM_REVISION
246         done
247      else
248         CUSTOM_REVISION=${newest_revision}
249      fi
250      if [[ -d ${trunk_dir} ]] && [[ "$(svn status ${trunk_dir}/)" == ""  ]]; then
251         palm_svn_update
252      else
253         rm -rf ${trunk_dir}
254         mkdir -p ${install_prefix}
255         palm_svn_checkout
256      fi
257      if [[ "$(svn status ${trunk_dir}/)" != ""  ]]; then
258         printf "%s \e[1;31mnot able\e[0m to optain a working copy of ${program_name}. Please optain it manually.\n" "-- Subversion was"
259         palm_read_yn "Is there a working copy of ${program_name} in the current directory?" "IS_TRUNK"
260         [[ "$IS_TRUNK" != "y" ]] && palm_installer_abort_message
261      fi
262   fi
263   if [[ -d ${trunk_dir} ]]; then
264      palm_svn_check_local
265      if [[ "$(svn status ${trunk_dir}/)" == ""  ]]; then
266         local tmp_revision=( $(svn info ${trunk_dir}/ | grep Revision:) )
267         local new_revision=${tmp_revision[1]}
268         printf "%s \e[1;32mfound\e[0m.\n" "-- ${program_name} (revision: ${new_revision})"
269      else
270         printf "%s It is \e[1;33massumed\e[0m a working copy of ${program_name} can be found in the current directory.\n" "--"
271      fi
272   else
273      printf "%s \e[1;31m${program_name} was not able to find a working PALM copy. Aborting!\e[0m\n" "--"
274      palm_installer_abort_message
275   fi
276   printf "\n"
277   hrule
278   printf "| \e[1;32m%-${number_of_cols}s\e[0m |\n" "${program_name} installer initialization done."
279   hrule
280   palm_read_yn "Are you happy with your choices and ready to continue?" "RESPONSE_CONFIGURE"
281   if [[ "$RESPONSE_CONFIGURE" != "y" ]]; then
282      palm_installer_abort_message
283   fi
284}
285
286# check if svn server is reachable
287palm_svn_check_remote() {
288   svn info --username "$SVN_USER" ${palm_svn_url} > /dev/null
289   local status=$?
290   if [[ $status -ne 0 ]]; then
291      printf "\e[1;31m%-${number_of_cols}s\e[0m \n" "ERROR: svn server not reachable."
292      palm_installer_error_message
293   fi
294}
295# check if svn server is reachable
296palm_svn_check_local() {
297   svn info ${trunk_dir}/ > /dev/null
298   local status=$?
299   if [[ $status -ne 0 ]]; then
300      printf "\e[1;31m%-${number_of_cols}s\e[0m \n" "ERROR: local svn repository is not healthy."
301      palm_installer_error_message
302   fi
303}
304
305# get svn username
306palm_svn_get_username() {
307   for svn_auth_file in ~/.subversion/auth/svn.simple/*; do
308      if [[ $(cat ${svn_auth_file} | grep "${palm_base_url}") != "" ]]; then
309         cat ${svn_auth_file} | awk '/^K / { key=1; val=0; } /^V / { key=0; val=1; } ! /^[KV] / { if(key) { kname=$1; } if(val && kname == "username") { print $1; val = 0; } }'
310         return 0
311      fi
312   done
313   read -p "-- Please enter your ${program_name} svn username: " username
314   echo ${username}
315   return 0
316}
317
318# check if svn server is reachable
319palm_svn_newest_revision() {
320   local tmp_revision=( $(svn info --username "$SVN_USER" ${palm_svn_url} | grep Revision:) )
321   echo ${tmp_revision[1]}
322}
323
324# check if svn server is reachable
325palm_svn_local_revision() {
326   local tmp_revision=( $(svn info ${trunk_dir}/ | grep Revision:) )
327   echo ${tmp_revision[1]}
328}
329
330
331palm_svn_checkout() {
332   local n=$(($(svn info --username "$SVN_USER" -R ${palm_svn_url} | grep "URL: " | uniq | wc -l)/2))
333   printf "%s" "-- Number of files to be downloaded: $n\n"
334   local i=1
335   while read line filename; do
336      if [[ $i -le $n ]]; then
337         ((++i))
338         local percent=$(printf "%3s" "$(((${i:-0}*100)/${n:-100}))")
339         local status_line=$(printf "[ %s%% ] Downloading file: %s" "$percent" "$(basename $filename)")
340         printf "\r-- %$(($(tput cols)-3))s" " "
341         printf "\r-- %s" "$status_line"
342      fi
343   done < <(svn checkout --username "$SVN_USER" ${CUSTOM_REVISION:+"-r${CUSTOM_REVISION}"} ${palm_svn_url} ${trunk_dir})
344   printf "\r-- %$(($(tput cols)-3))s" " "
345   printf "\r-- [ %3s%% ] \e[1;32m%s\e[0m\n" "100" "Download finished!"
346}
347
348palm_svn_update() {
349   local n=$(($(svn diff -r ${existing_revision}:${CUSTOM_REVISION} --summarize ${palm_svn_url} | uniq | wc -l)/2))
350   printf "%s\n" "-- Number of files to be updated: $n"
351   local i=1
352   while read line filename; do
353      if [[ $i -le $n ]]; then
354         ((++i))
355         local percent=$(printf "%3s" "$(((${i:-0}*100)/${n:-100}))")
356         local status_line=$(printf "[ %s%% ] Updating file: %s" "$percent" "$(basename $filename)")
357         printf "\r-- %$(($(tput cols)-3))s" " "
358         printf "\r-- %s" "$status_line"
359      fi
360   done < <(svn update ${CUSTOM_REVISION:+"-r${CUSTOM_REVISION}"} ${trunk_dir})
361   printf "\r-- %$(($(tput cols)-3))s" " "
362   printf "\r-- [ %3s%% ] \e[1;32m%s\e[0m\n" "100" "Update finished!"
363}
364
365# install PALM
366palm_installer_build() {
367   printf "%s\n" "${program_name} installer is configuring using cmake..."
368   palm_installer_create_files
369   rm -rf ${build_dir}
370   mkdir -p ${build_dir}
371   cd ${build_dir}
372   cmake -Wno-dev ${CUSTOM_FORTRAN_COMPILER:+-DCMAKE_Fortran_COMPILER=}${CUSTOM_FORTRAN_COMPILER} \
373         ${NETCDF_C_ROOT:+-DNETCDF_C_ROOT=}${NETCDF_C_ROOT} \
374         ${NETCDF_FORTRAN_ROOT:+-DNETCDF_FORTRAN_ROOT=}${NETCDF_FORTRAN_ROOT} \
375         -DCMAKE_BUILD_TYPE=Release \
376         ${install_prefix:+-DCMAKE_INSTALL_PREFIX=}${install_prefix} \
377         -DCMAKE_USERNAME=${USER} \
378         ${source_dir}
379   if [[ $? -ne 0 ]]; then
380      hrule
381      printf "| \e[1;31m%-${number_of_cols}s\e[0m |\n" "Configuration failed!"
382      palm_installer_ticket_message
383      hrule
384      exit 1
385   else
386      hrule
387      printf "| \e[1;32m%-${number_of_cols}s\e[0m |\n" "Configuration finished!"
388      hrule
389   fi
390   palm_read_yn "Please check the configuration!!! Would you like to continue?" "RESPONSE_CONFIGURE"
391   if [[ "$RESPONSE_CONFIGURE" != "y" ]]; then
392      palm_installer_abort_message
393   fi
394   cd ${install_prefix}
395   rm -rf ${source_dir}
396   rm -rf MAKE_DEPOSITORY_parallel
397   ${trunk_dir}/SCRIPTS/mbuild -v -K "parallel" -u
398   ${trunk_dir}/SCRIPTS/mbuild -v -K "parallel"
399}
400
401palm_installer_set_path() {
402   [[ -w ${HOME}/.mybashrc ]] && shell_profile=${HOME}/.mybashrc
403   if [[ ! -w ${shell_profile} ]]; then
404      printf "\e[1;31mWARNING\e[0m: ${program_name} binary \e[1;31mpath could not be written\e[0m to \"${shell_profile}\"\n"
405      printf "In order to run the ${program_name} execution script \"mrun\" you need to set the following paths\n"
406      printf "   export PALM_BIN=${trunk_dir}/SCRIPTS\n"
407      printf "   export PATH=\$PALM_BIN:\$PATH\n"
408   elif grep -q "^export PALM_BIN=${trunk_dir}/SCRIPTS" ${shell_profile}; then
409      printf "${program_name} binary \e[1;32mpath already set correctly\e[0m in \"${shell_profile}\"\n"
410   else
411      if grep -q "PALM_BIN" ${shell_profile}; then
412         sed -i "s@^[^#]\(.*PALM_BIN.*\)@#e\1@" ${shell_profile}
413         printf "${program_name} binary \e[1;32mpath updated\e[0m in \"${shell_profile}\""
414      else
415         printf "${program_name} binary \e[1;32mpath written\e[0m to \"${shell_profile}\""
416      fi
417      cat >> ${shell_profile} << EOF
418#-------------------------------------------------------------------------------
419##PALM##
420export PALM_BIN=${trunk_dir}/SCRIPTS
421export PATH=\$PALM_BIN:\$PATH
422
423EOF
424   fi
425   export PALM_BIN=${trunk_dir}/SCRIPTS
426   export PATH=$PALM_BIN:$PATH
427   echo " "
428}
429
430palm_installer_test() {
431   hrule
432   printf "Testing ${program_name} with \"${1}\"... "
433   source ${shell_profile}
434   local input_dir=${install_prefix}/JOBS/${1}/INPUT/
435   local monitoring_dir=${install_prefix}/JOBS/${1}/MONITORING/
436   local test_dir=${trunk_dir}/INSTALL
437   if [[ ! -f ${test_dir}/${1}_p3d ]] || [[ ! -f ${test_dir}/${1}_rc ]]; then
438      printf "\e[1;31m test not found\e[0m\n"
439      return 1
440   fi
441   rm -rf ${monitoring_dir}
442   mkdir -p ${input_dir}
443   cp ${test_dir}/${1}_p3d ${input_dir}
444   [[ -f ${test_dir}/${1}_topo ]] && cp ${test_dir}/${1}_topo ${input_dir}
445   ${trunk_dir}/SCRIPTS/mrun -d ${1} -r "d3#" -h "lclocal" -K "parallel" -X "$NUM_PROC" -T "$NUM_PROC" -v -B > ${install_prefix}/${logfile_test} 2>&1
446   grep -A 99999 "Run-control output" JOBS/${1}/MONITORING/${1}_rc 1> ${install_prefix}/RC_LOCAL 2> /dev/null
447   grep -A 99999 "Run-control output" ${test_dir}/${1}_rc 1> ${install_prefix}/RC_DEFAULT 2> /dev/null
448   diff_output=$(diff ${install_prefix}/RC_DEFAULT ${install_prefix}/RC_LOCAL)
449   rm ${install_prefix}/RC_LOCAL ${install_prefix}/RC_DEFAULT
450   if [[ "${diff_output}" == "" ]]; then
451      printf "\e[1;32m passed\e[0m\n"
452      return 0
453   else
454      printf "\e[1;31m failed\e[0m\n"
455      test_status="failed"
456      return 1
457   fi
458}
459
460palm_installer_test_suite() {
461   rm -f ${install_prefix}/${logfile_test}
462   for test_path in ${trunk_dir}/INSTALL/*_p3d; do
463      testname_p3d=$(basename $test_path)
464      palm_installer_test "${testname_p3d%_p3d}"
465   done
466   hrule
467   cat ${install_prefix}/${logfile_test} >> ${logfile_all}
468   if [[ "${test_status}" == "failed" ]]; then
469      printf "| \e[1;31m%-${number_of_cols}s\e[0m |\n" "Some tests failed. ${program_name} installation not successful :-("
470      printf "| \e[1;31m%-${number_of_cols}s\e[0m |\n" "More detailed information regarding the failure can be found in file:"
471      printf "| \e[1;31m%-${number_of_cols}s\e[0m |\n" "      ${install_prefix}/${logfile_test}"
472      palm_installer_ticket_message
473      hrule
474      exit 1
475   else
476      printf "| \e[1;32m%-${number_of_cols}s\e[0m |\n" "All found tests passed. ${program_name} installation successful :-)"
477      rm -f ${install_prefix}/${logfile_test}
478      rm -rf ${install_prefix}/tmp/*
479      hrule
480   fi
481}
482
483################################################################################
484
485# startup message
486palm_installer_startup_message() {
487   printf "\n"
488   hrule
489   printf "|                                                                        |\n"
490   printf "|                       PALM installer (${installer_version})                         |\n"
491   printf "|                   https://palm.muk.uni-hannover.de/                    |\n"
492   printf "|                                                                        |\n"
493}
494
495# shutdown message
496palm_installer_shutdown_message() {
497   hrule
498   printf "| %-${number_of_cols}s |\n" "${program_name} installer finished."
499   hrule
500   rm -f ${logfile_all}
501   exit 0
502}
503
504# shutdown message
505palm_installer_abort_message() {
506   hrule
507   printf "| \e[1;31m%-${number_of_cols}s\e[0m |\n" "${program_name} installer aborted."
508   hrule
509   exit 0
510}
511
512# error wrap-up message
513palm_installer_error_message() {
514   hrule
515   printf "| \e[1;31m%-${number_of_cols}s\e[0m \n" "${program_name} installer crashed."
516   palm_installer_ticket_message
517   hrule
518   exit 1
519}
520
521palm_installer_ticket_message() {
522   printf "| \e[1;31m%-${number_of_cols}s\e[0m \n" " "
523   printf "| \e[1;31m%-${number_of_cols}s\e[0m \n" "In order to get help, please use our ticket system at:"
524   printf "| \e[1;31m%-${number_of_cols}s\e[0m \n" "   \"https://palm.muk.uni-hannover.de/trac/wiki/help\""
525   printf "| \e[1;31m%-${number_of_cols}s\e[0m \n" " "
526   printf "| \e[1;31m%-${number_of_cols}s\e[0m \n" "Please allways attach the following file to the ticket:"
527   printf "| \e[1;31m%-${number_of_cols}s\e[0m \n" "   \"${logfile_all}\""
528}
529
530hrule() {
531   printf "#"
532   printf -- '-%.0s' {1..72}
533   printf "#\n"
534}
535
536palm_read_yn() {
537   sleep 0.1
538   while true; do
539   read -p "-- ${1} (y|n): " CURRENT_RESPONSE
540   if [[ "${CURRENT_RESPONSE}" == "y" ]] || [[ "${CURRENT_RESPONSE}" == "n" ]]; then
541      eval ${2}="${CURRENT_RESPONSE}"
542      break
543   fi
544   done
545}
546
547palm_installer_help() {
548   hrule
549   printf "| %-${number_of_cols}s |\n" "USAGE: bash ${0} [--init|--version|--prep]"
550   hrule
551   rm -f ${logfile_all}
552   exit 0
553}
554
555palm_installer_version() {
556   hrule
557   printf "| %-${number_of_cols}s |\n" "VERSION: This PALM installer has version number: ${installer_version}"
558   hrule
559   rm -f ${logfile_all}
560   exit 0
561}
562
563palm_post_installer_help() {
564   hrule
565   printf "| %-${number_of_cols}s \n" " "
566   printf "| %-${number_of_cols}s \n" "-- To use ${program_name} it is required to update your PATH variable. Please type:"
567   printf "| %-${number_of_cols}s \n" " "
568   printf "| %-${number_of_cols}s \n" "      source ${shell_profile}"
569   printf "| %-${number_of_cols}s \n" " "
570   printf "| %-${number_of_cols}s \n" "   or restart your shell."
571   printf "| %-${number_of_cols}s \n" " "
572   printf "| %-${number_of_cols}s \n" "-- To work with ${program_name} please go to your ${program_name} base directory:"
573   printf "| %-${number_of_cols}s \n" " "
574   printf "| %-${number_of_cols}s \n" "      cd ${install_prefix}"
575   printf "| %-${number_of_cols}s \n" " "
576   printf "| %-${number_of_cols}s \n" "-- To start the model, please use \"mrun\" with appropriate options. For example:"
577   printf "| %-${number_of_cols}s \n" " "
578   printf "| %-${number_of_cols}s \n" "      mrun -d example_cbl -r \"d3#\" -h \"lclocal\" -K \"parallel\" -X \"4\" -T \"4\"      "
579   printf "| %-${number_of_cols}s \n" "                   |           |          |            |          |      |       "
580   printf "| %-${number_of_cols}s \n" "               Job name        |   host identifier     | number of cores |       "
581   printf "| %-${number_of_cols}s \n" "                        I/O control list     configuration block   tasks per node"
582   printf "| %-${number_of_cols}s \n" " "
583   printf "| %-${number_of_cols}s \n" "-- There is a GUI called \"mrungui\" available as well (Qt4 required)."
584   printf "| %-${number_of_cols}s \n" " "
585   printf "| %-${number_of_cols}s \n" "-- Edit \".mrun.config\" to customize this ${program_name} installation."
586   printf "| %-${number_of_cols}s \n" "-- To rebuild ${program_name} type: \"mbuild\"."
587   printf "| %-${number_of_cols}s \n" " "
588   printf "| %-${number_of_cols}s \n" "-- For further questions go to: https://palm.muk.uni-hannover.de/."
589   printf "| %-${number_of_cols}s \n" " "
590}
591
592palm_installer_prep_mpi() {
593   sudo apt-get install mpich
594}
595
596palm_installer_prep_netcdf() {
597   sudo apt-get install libnetcdf-dev libnetcdff-dev ncview
598}
599
600palm_installer_prep_gt() {
601   sudo apt-get install libqt4-dev
602}
603
604palm_installer_prep_fftw() {
605   sudo apt-get install libfftw3-dev
606}
607
608palm_installer_create_files() {
609   mkdir -p ${source_dir}
610   cat > ${source_dir}/.mrun.config.in << EOF
611#\$Id: .mrun.config.gfortran 1446 2014-08-07 10:08:56Z knoop $
612#column 1          column 2                                   column 3
613#name of variable  value of variable (~ must not be used)     scope
614#------------------------------------------------------------------------------#
615%mainprog          palm.f90
616%base_directory    @CMAKE_INSTALL_PREFIX@
617%base_data         \$base_directory/JOBS
618%source_path       \$base_directory/trunk/SOURCE
619%add_source_path   \$base_directory/USER_CODE/\$fname
620%depository_path   \$base_directory/MAKE_DEPOSITORY
621#
622# Enter your own host below by adding another line containing in the second
623# column your hostname (as provided by the unix command "hostname") and in the
624# third column the host identifier. Depending on your operating system, the
625# first characters of the host identifier should be "lc" (Linux cluster), "ibm"
626# (IBM-AIX), or "nec" (NEC-SX), respectively.
627#
628# The next line is just an example. Add your own line below or replace this line.
629%host_identifier   @PALM_HOSTNAME@  lclocal
630#
631#
632# The next block contains all informations for compiling the PALM code
633# and for generating and running the PALM executable using MPI. Replace all
634# required paths (given in <>) by the respective paths valid on your host.
635# Also replace lclocal by your host identifier (for example "lcmy")
636# in each line!
637# Compilernames, cpp-options and compiler-options are assuming
638# an GNU-Compiler and mpich2 on this host! Please change
639# appropriately, if you are using a different compiler / MPI-Version.
640#
641# highly optimized mode
642%remote_username   @CMAKE_USERNAME@                       lclocal parallel
643%tmp_user_catalog  @CMAKE_INSTALL_PREFIX@/tmp             lclocal parallel
644%tmp_data_catalog  @CMAKE_INSTALL_PREFIX@/RESTART_DATA    lclocal parallel
645%compiler_name     @MPI_Fortran_COMPILER@                 lclocal parallel
646%compiler_name_ser @CMAKE_Fortran_COMPILER@               lclocal parallel
647%cpp_options       @PALM_CPP_OPTIONS_STR@                 lclocal parallel
648%fopts             @CMAKE_Fortran_FLAGS_RELEASE_STR@      lclocal parallel
649%lopts             @CMAKE_Fortran_FLAGS_RELEASE_STR@      lclocal parallel
650%mopts             -j:@PALM_CORES@                        lclocal parallel
651%netcdf_inc        -I:@NETCDF_INCLUDES@                   lclocal parallel
652%netcdf_lib        @NETCDF_LIBRARIES@                     lclocal parallel
653%fftw_inc          -I:@FFTW_INCLUDES@                     lclocal parallel
654%fftw_lib          @FFTW_LIBRARIES@                       lclocal parallel
655# if you want to use your own hostfile, uncomment next line
656#%hostfile          \$base_directory/.hostfile             lclocal parallel
657# if you want to load modules on the remote host, use the following line
658#%modules           <replace_by_the_modules_to_be_loaded> lclocal parallel
659# if you want to perform initial commands on ssh connections, use the following line
660#%login_init_cmd    <replace_by_the_inital_commands>      lclocal parallel
661#
662# debug/trace mode
663%remote_username   @CMAKE_USERNAME@                       lclocal parallel trace
664%tmp_user_catalog  @CMAKE_INSTALL_PREFIX@/tmp             lclocal parallel trace
665%tmp_data_catalog  @CMAKE_INSTALL_PREFIX@/RESTART_DATA    lclocal parallel trace
666%compiler_name     @MPI_Fortran_COMPILER@                 lclocal parallel trace
667%compiler_name_ser @CMAKE_Fortran_COMPILER@               lclocal parallel trace
668%cpp_options       @PALM_CPP_OPTIONS_STR@                 lclocal parallel trace
669%fopts             @CMAKE_Fortran_FLAGS_DEBUG_STR@        lclocal parallel trace
670%lopts             @CMAKE_Fortran_FLAGS_DEBUG_STR@        lclocal parallel trace
671%mopts             -j:@PALM_CORES@                        lclocal parallel trace
672%netcdf_inc        -I:@NETCDF_INCLUDES@                   lclocal parallel trace
673%netcdf_lib        @NETCDF_LIBRARIES@                     lclocal parallel trace
674%fftw_inc          -I:@FFTW_INCLUDES@                     lclocal parallel trace
675%fftw_lib          @FFTW_LIBRARIES@                       lclocal parallel trace
676# if you want to use your own hostfile, uncomment next line
677#%hostfile          \$base_directory/.hostfile             lclocal parallel trace
678# if you want to load modules on the remote host, use the following line
679#%modules           <replace_by_the_modules_to_be_loaded> lclocal parallel trace
680# if you want to perform initial commands on ssh connections, use the following line
681#%login_init_cmd    <replace_by_the_inital_commands>      lclocal parallel trace
682#
683#
684%write_binary                true                             restart
685#
686#------------------------------------------------------------------------------#
687# INPUT-commands, executed before running PALM - lines must start with "IC:"
688#------------------------------------------------------------------------------#
689#IC:
690#
691#------------------------------------------------------------------------------#
692# ERROR-commands - executed when program terminates abnormally
693#------------------------------------------------------------------------------#
694EC:[[ \\\$locat = execution ]]  &&  cat  RUN_CONTROL
695#
696#------------------------------------------------------------------------------#
697# OUTPUT-commands - executed when program terminates normally
698#------------------------------------------------------------------------------#
699#
700# Combine 1D- and 3D-profile output (these files are not usable for plotting)
701OC:[[ -f LIST_PROFIL_1D     ]]  &&  cat  LIST_PROFIL_1D  >>  LIST_PROFILE
702OC:[[ -f LIST_PROFIL        ]]  &&  cat  LIST_PROFIL     >>  LIST_PROFILE
703#
704# Combine all particle information files
705OC:[[ -f PARTICLE_INFOS/_0000 ]]  &&  cat  PARTICLE_INFOS/* >> PARTICLE_INFO
706#
707#------------------------------------------------------------------------------#
708# List of input-files
709#------------------------------------------------------------------------------#
710PARIN                    in:job        d3#          \$base_data/\$fname/INPUT    _p3d
711PARIN                    in:job        d3f          \$base_data/\$fname/INPUT    _p3df
712rrtmg_lw.nc              in:locopt     d3#:d3f      \$base_data/\$fname/INPUT    _rlw nc
713rrtmg_sw.nc              in:locopt     d3#:d3f      \$base_data/\$fname/INPUT    _rsw nc
714RAD_SND_DATA             in:locopt     d3#:d3f      \$base_data/\$fname/INPUT    _rsnd nc
715TOPOGRAPHY_DATA          in:locopt     d3#:d3f      \$base_data/\$fname/INPUT    _topo
716NUDGING_DATA             in:locopt     d3#:d3f      \$base_data/\$fname/INPUT    _nudge
717LSF_DATA                 in:locopt     d3#:d3f      \$base_data/\$fname/INPUT    _lsf
718BININ                    in:loc:flpe   d3f:cycfill  \$base_data/\$fname/RESTART  _d3d
719PARTICLE_RESTART_DATA_IN in:loc:flpe   prtf         \$base_data/\$fname/RESTART  _rprt
720DATA_1D_PR_NETCDF        in:locopt     prf          \$base_data/\$fname/OUTPUT   _pr     nc
721DATA_1D_SP_NETCDF        in:locopt     spf          \$base_data/\$fname/OUTPUT   _sp     nc
722DATA_1D_TS_NETCDF        in:locopt     tsf          \$base_data/\$fname/OUTPUT   _ts     nc
723DATA_1D_PTS_NETCDF       in:locopt     ptsf         \$base_data/\$fname/OUTPUT   _pts    nc
724DATA_2D_XY_NETCDF        in:locopt     xyf          \$base_data/\$fname/OUTPUT   _xy     nc
725DATA_2D_XY_AV_NETCDF     in:locopt     xyf          \$base_data/\$fname/OUTPUT   _xy_av  nc
726DATA_2D_XZ_NETCDF        in:locopt     xzf          \$base_data/\$fname/OUTPUT   _xz     nc
727DATA_2D_XZ_AV_NETCDF     in:locopt     xzf          \$base_data/\$fname/OUTPUT   _xz_av  nc
728DATA_2D_YZ_NETCDF        in:locopt     yzf          \$base_data/\$fname/OUTPUT   _yz     nc
729DATA_2D_YZ_AV_NETCDF     in:locopt     yzf          \$base_data/\$fname/OUTPUT   _yz_av  nc
730DATA_3D_NETCDF           in:locopt     3df          \$base_data/\$fname/OUTPUT   _3d     nc
731DATA_3D_AV_NETCDF        in:locopt     3df          \$base_data/\$fname/OUTPUT   _3d_av  nc
732DATA_PRT_NETCDF          in:locopt:pe  prtf         \$base_data/\$fname/OUTPUT   _prt
733#
734#------------------------------------------------------------------------------#
735# List of output-files
736#------------------------------------------------------------------------------#
737BINOUT                    out:loc:flpe restart   \$base_data/\$fname/RESTART  _d3d
738PARTICLE_RESTART_DATA_OUT out:loc:flpe prt#:prtf \$base_data/\$fname/RESTART  _rprt
739#
740RUN_CONTROL       out:loc:tr   d3#     \$base_data/\$fname/MONITORING  _rc
741RUN_CONTROL       out:loc:tra  d3f     \$base_data/\$fname/MONITORING  _rc
742HEADER            out:loc:tr   d3#     \$base_data/\$fname/MONITORING  _header
743HEADER            out:loc:tra  d3f     \$base_data/\$fname/MONITORING  _header
744CPU_MEASURES      out:loc:tr   d3#     \$base_data/\$fname/MONITORING  _cpu
745CPU_MEASURES      out:loc:tra  d3f     \$base_data/\$fname/MONITORING  _cpu
746#
747DATA_1D_PR_NETCDF    out:loc:tr   pr#:prf   \$base_data/\$fname/OUTPUT  _pr     nc
748DATA_1D_SP_NETCDF    out:loc:tr   sp#:spf   \$base_data/\$fname/OUTPUT  _sp     nc
749DATA_1D_TS_NETCDF    out:loc:tr   ts#:tsf   \$base_data/\$fname/OUTPUT  _ts     nc
750DATA_1D_PTS_NETCDF   out:loc:tr   pts#:ptsf \$base_data/\$fname/OUTPUT  _pts    nc
751DATA_2D_XY_NETCDF    out:loc:tr   xy#:xyf   \$base_data/\$fname/OUTPUT  _xy     nc
752DATA_2D_XY_AV_NETCDF out:loc:tr   xy#:xyf   \$base_data/\$fname/OUTPUT  _xy_av  nc
753DATA_2D_XZ_NETCDF    out:loc:tr   xz#:xzf   \$base_data/\$fname/OUTPUT  _xz     nc
754DATA_2D_XZ_AV_NETCDF out:loc:tr   xz#:xzf   \$base_data/\$fname/OUTPUT  _xz_av  nc
755DATA_2D_YZ_NETCDF    out:loc:tr   yz#:yzf   \$base_data/\$fname/OUTPUT  _yz     nc
756DATA_2D_YZ_AV_NETCDF out:loc:tr   yz#:yzf   \$base_data/\$fname/OUTPUT  _yz_av  nc
757DATA_3D_NETCDF       out:loc:tr   3d#:3df   \$base_data/\$fname/OUTPUT  _3d     nc
758DATA_3D_AV_NETCDF    out:loc:tr   3d#:3df   \$base_data/\$fname/OUTPUT  _3d_av  nc
759DATA_MASK_01_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m01     nc
760DATA_MASK_01_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m01_av  nc
761DATA_MASK_02_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m02     nc
762DATA_MASK_02_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m02_av  nc
763DATA_MASK_03_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m03     nc
764DATA_MASK_03_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m03_av  nc
765DATA_MASK_04_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m04     nc
766DATA_MASK_04_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m04_av  nc
767DATA_MASK_05_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m05     nc
768DATA_MASK_05_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m05_av  nc
769DATA_MASK_06_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m06     nc
770DATA_MASK_06_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m06_av  nc
771DATA_MASK_07_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m07     nc
772DATA_MASK_07_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m07_av  nc
773DATA_MASK_08_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m08     nc
774DATA_MASK_08_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m08_av  nc
775DATA_MASK_09_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m09     nc
776DATA_MASK_09_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m09_av  nc
777DATA_MASK_10_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m10     nc
778DATA_MASK_10_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m10_av  nc
779DATA_MASK_11_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m11     nc
780DATA_MASK_11_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m11_av  nc
781DATA_MASK_12_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m12     nc
782DATA_MASK_12_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m12_av  nc
783DATA_MASK_13_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m13     nc
784DATA_MASK_13_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m13_av  nc
785DATA_MASK_14_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m14     nc
786DATA_MASK_14_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m14_av  nc
787DATA_MASK_15_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m15     nc
788DATA_MASK_15_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m15_av  nc
789DATA_MASK_16_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m16     nc
790DATA_MASK_16_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m16_av  nc
791DATA_MASK_17_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m17     nc
792DATA_MASK_17_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m17_av  nc
793DATA_MASK_18_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m18     nc
794DATA_MASK_18_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m18_av  nc
795DATA_MASK_19_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m19     nc
796DATA_MASK_19_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m19_av  nc
797DATA_MASK_20_NETCDF    out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m20     nc
798DATA_MASK_20_AV_NETCDF out:loc:tr ma#:maf   \$base_data/\$fname/OUTPUT  _m20_av  nc
799DATA_PRT_NETCDF      out:loc:trpe prt#:prtf \$base_data/\$fname/OUTPUT  _prt    nc
800DATA_DVR             out:loc:trpe dvr       \$base_data/\$fname/OUTPUT  _dvr
801#
802DVRP_LOG          out:loc:tr   dv#       \$base_data/\$fname/MONITORING  _dvrp_log
803DVRP_LOG          out:loc:tra  dvf       \$base_data/\$fname/MONITORING  _dvrp_log
804PARTICLE_INFO     out:loc:tr   pt#       \$base_data/\$fname/MONITORING  _prt_info
805PARTICLE_INFO     out:loc:tra  ptf       \$base_data/\$fname/MONITORING  _prt_info
806PARTICLE_DATA     out:loc:flpe prt#:prtf \$base_data/\$fname/OUTPUT      _prt_dat
807#
808#------------------------------------------------------------------------------#
809# A BLANK LINE MUST FOLLOW
810
811EOF
812
813   cat > ${source_dir}/CMakeLists.txt << EOF
814# This is the CMake configuration file for PALM
815
816cmake_minimum_required (VERSION 2.8)
817
818# set program name
819set(PALM_PROGRAM_NAME "PALM")
820
821project(\${PALM_PROGRAM_NAME} NONE)
822exec_program( grep ARGS "-c ^processor /proc/cpuinfo" OUTPUT_VARIABLE PALM_CORES)
823exec_program( hostname OUTPUT_VARIABLE PALM_HOSTNAME)
824
825# .mrun.config locations
826set(config_in \${CMAKE_CURRENT_SOURCE_DIR}/.mrun.config.in)
827set(config \${CMAKE_INSTALL_PREFIX}/.mrun.config)
828
829# include local cmake files
830set(PALM_CMAKE_FILES \${CMAKE_CURRENT_SOURCE_DIR})
831list(APPEND CMAKE_MODULE_PATH \${PALM_CMAKE_FILES})
832
833# enabling Fortran language support
834enable_language(Fortran) # required to compile the main model and all utilities
835
836# check for Fortran MPI support
837find_package(MPI REQUIRED)
838
839# enabling C++ language support
840enable_language(CXX)     # required for MPI and to compile the mrungui
841
842# check for netCDF
843#set(NETCDF_C "YES")
844set(NETCDF_FORTRAN "YES")
845find_package (NetCDF REQUIRED)
846find_program(NETCDF_FORTRAN_COMPILER_FULL NAMES \${NETCDF_FORTRAN_COMPILER})
847if(NOT \${CMAKE_Fortran_COMPILER} STREQUAL \${NETCDF_FORTRAN_COMPILER_FULL} )
848   message(WARNING "Fortran compiler \"\${CMAKE_Fortran_COMPILER}\" does not match netCDF Fortran compiler \"\${NETCDF_FORTRAN_COMPILER_FULL}\".")
849else()
850   message(STATUS "Fortran compiler matches netCDF Fortran compiler.")
851endif()
852
853# extract subversion info
854find_package(Subversion)
855if(SUBVERSION_FOUND)
856   Subversion_WC_INFO(\${PROJECT_SOURCE_DIR}/../trunk PALM)
857   message(STATUS "Your \${PALM_PROGRAM_NAME} installation will be based on revision \${PALM_WC_REVISION}.")
858else(SUBVERSION_FOUND)
859   message(WARNING "Subversion not found. Wondering how you aquired the PALM code. :-)")
860endif(SUBVERSION_FOUND)
861
862# check for fftw
863find_package(FFTW)
864if(FFTW_FOUND)
865   message(STATUS "\${PALM_PROGRAM_NAME} is using an external fftw library.")
866   list(APPEND PALM_CPP_OPTIONS __fftw)
867else(FFTW_FOUND)
868   message(STATUS "\${PALM_PROGRAM_NAME} is using the buildin fft algorithm.")
869endif(FFTW_FOUND)
870
871# find qt4
872find_package(Qt4)
873
874# compiler flag management
875if(\${CMAKE_Fortran_COMPILER_ID} STREQUAL "Cray")
876   set(CMAKE_Fortran_FLAGS_RELEASE "-em -K trap=fp -O3 -hnoomp -hnoacc -hfp3 -hdynamic -dynamic")
877   string(REPLACE " " ":" CMAKE_Fortran_FLAGS_RELEASE_STR "\${CMAKE_Fortran_FLAGS_RELEASE}")
878   set(CMAKE_Fortran_FLAGS_DEBUG "-eD -em -g -R b -K trap=fp -O0 -hnoomp -hnoacc")
879   string(REPLACE " " ":" CMAKE_Fortran_FLAGS_DEBUG_STR "\${CMAKE_Fortran_FLAGS_DEBUG}")
880   set(PALM_CPP_FLAGS "-eZ")
881elseif(\${CMAKE_Fortran_COMPILER_ID} STREQUAL "Intel")
882   set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -fp-model source -fno-alias -fpe0 -ftz -no-prec-div -no-prec-sqrt -ip -nbs -diag-disable 8290,8291")
883   string(REPLACE " " ":" CMAKE_Fortran_FLAGS_RELEASE_STR "\${CMAKE_Fortran_FLAGS_RELEASE}")
884   set(CMAKE_Fortran_FLAGS_DEBUG " -O0 -g -debug -traceback -C -w -xT -check nooutput_conversion -convert little_endian -fno-alias -fpe0 -ftz -no-prec-div -no-prec-sqrt -ip -nbs -diag-disable 8290,8291")
885   string(REPLACE " " ":" CMAKE_Fortran_FLAGS_DEBUG_STR "\${CMAKE_Fortran_FLAGS_DEBUG}")
886   set(PALM_CPP_FLAGS "-cpp")
887elseif(\${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU")
888   set(CMAKE_Fortran_FLAGS_RELEASE "-Ofast -ffree-line-length-none")
889   string(REPLACE " " ":" CMAKE_Fortran_FLAGS_RELEASE_STR "\${CMAKE_Fortran_FLAGS_RELEASE}")
890   set(CMAKE_Fortran_FLAGS_DEBUG "-g -Wall -Wextra -fbacktrace -ffree-line-length-none")
891   string(REPLACE " " ":" CMAKE_Fortran_FLAGS_DEBUG_STR "\${CMAKE_Fortran_FLAGS_DEBUG}")
892   set(PALM_CPP_FLAGS "-cpp")
893endif()
894
895# adding cpp options
896list(APPEND PALM_CPP_OPTIONS MPI_REAL=MPI_DOUBLE_PRECISION)
897list(APPEND PALM_CPP_OPTIONS MPI_2REAL=MPI_2DOUBLE_PRECISION)
898if(NETCDF_FOUND)
899   list(APPEND PALM_CPP_OPTIONS __netcdf)
900endif()
901
902string(REPLACE ";" ":-D" PALM_CPP_OPTIONS_STR_1 "\${PALM_CPP_OPTIONS}")
903set(PALM_CPP_OPTIONS_STR "\${PALM_CPP_FLAGS}:-D\${PALM_CPP_OPTIONS_STR_1}")
904
905# configuring the .mrun.config
906configure_file(\${config_in} \${config} @ONLY)
907
908if(NOT FFTW_FOUND)
909   exec_program(sed ARGS -i '/%fftw_inc.*/d' \${config} OUTPUT_VARIABLE dummy)
910   exec_program(sed ARGS -i '/%fftw_lib.*/d' \${config} OUTPUT_VARIABLE dummy)
911endif(FFTW_FOUND)
912
913EOF
914
915   cat > ${source_dir}/FindFFTW.cmake << EOF
916# - Find FFTW
917# Find the native FFTW includes and library
918#
919#  FFTW_INCLUDES    - where to find fftw3.h
920#  FFTW_LIBRARIES   - List of libraries when using FFTW.
921#  FFTW_FOUND       - True if FFTW found.
922
923if (FFTW_INCLUDES)
924  # Already in cache, be silent
925  set (FFTW_FIND_QUIETLY TRUE)
926endif (FFTW_INCLUDES)
927
928#exec_program(sed ARGS -i '/%fftw_inc.*/d' \${config})
929#list(APPEND NETCDF_HINTS "\$ENV{LD_LIBRARY_PATH}")
930
931find_path (FFTW_INCLUDES fftw3.f03 HINTS \${NETCDF_HINTS} ENV LD_LIBRARY_PATH  PATH_SUFFIXES include Include)
932find_library(NETCDF_FORTRAN_LIB netcdff HINTS \${NETCDF_HINTS} ENV LD_LIBRARY_PATH PATH_SUFFIXES lib lib64)
933
934find_library (FFTW_LIBRARIES NAMES fftw3)
935
936# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if
937# all listed variables are TRUE
938include (FindPackageHandleStandardArgs)
939find_package_handle_standard_args (FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES)
940
941mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES)
942
943EOF
944
945   cat > ${source_dir}/FindNetCDF.cmake << EOF
946# - Find NetCDF
947# Find the native NetCDF includes and library
948#
949#  NETCDF_INCLUDES    - where to find netcdf.h, etc
950#  NETCDF_LIBRARIES   - Link these libraries when using NetCDF
951#  NETCDF_FOUND       - True if NetCDF found including required interfaces (see below)
952#
953# Your package can require certain interfaces to be FOUND by setting these
954#
955#  NETCDF_C           - require the C interface and link the C library
956#  NETCDF_CXX         - require the C++ interface and link the C++ library
957#  NETCDF_FORTRAN     - require the Fortran interface and link the Fortran library
958#
959# The following are not for general use and are included in
960# NETCDF_LIBRARIES if the corresponding option above is set.
961#
962#  NETCDF_LIBRARIES_C        - Just the C interface
963#  NETCDF_LIBRARIES_CXX      - C++ interface, if available
964#  NETCDF_LIBRARIES_FORTRAN  - Fortran 90 interface, if available
965#
966# Normal usage would be:
967#  set (NETCDF_FORTRAN "YES")
968#  find_package (NetCDF REQUIRED)
969#  target_link_libraries (uses_f90_interface \${NETCDF_LIBRARIES})
970
971if (NETCDF_INCLUDES AND NETCDF_LIBRARIES)
972  # Already in cache, be silent
973  set (NETCDF_FIND_QUIETLY TRUE)
974endif (NETCDF_INCLUDES AND NETCDF_LIBRARIES)
975
976
977macro(NETCDF_CONFIG flag output)
978    if(NETCDF_CONFIG_EXECUTABLE)
979        exec_program( \${NETCDF_CONFIG_EXECUTABLE} ARGS \${flag}
980            OUTPUT_VARIABLE \${output} RETURN_VALUE return_value)
981        if(NOT \${return_value} EQUAL 0 )
982            message( STATUS "Unable to determine \${flag} from \${NETCDF_CONFIG_EXECUTABLE}." )
983        endif()
984    endif(NETCDF_CONFIG_EXECUTABLE)
985endmacro()
986
987if(NETCDF_C_ROOT)
988   list(APPEND NETCDF_HINTS "\${NETCDF_C_ROOT}")
989else()
990   list(APPEND NETCDF_HINTS "\$ENV{NETCDF_ROOT}")
991endif()
992
993if(NETCDF_FORTRAN_ROOT)
994   list(APPEND NETCDF_HINTS "\${NETCDF_FORTRAN_ROOT}")
995else()
996   list(APPEND NETCDF_HINTS "\$ENV{NETCDF_ROOT}")
997endif()
998
999if(NETCDF_C_ROOT)
1000   find_program(NETCDF_C_CONFIG_EXECUTABLE NAMES nc-config
1001      HINTS \${NETCDF_HINTS} PATH_SUFFIXES bin Bin NO_DEFAULT_PATH
1002      DOC "NETCDF CONFIG PROGRAM. Used to detect NETCDF compile flags." )
1003else()
1004   find_program(NETCDF_C_CONFIG_EXECUTABLE NAMES nc-config
1005      HINTS \${NETCDF_HINTS} PATH_SUFFIXES bin Bin
1006      DOC "NETCDF CONFIG PROGRAM. Used to detect NETCDF compile flags." )
1007endif()
1008
1009set(NETCDF_CONFIG_EXECUTABLE \${NETCDF_C_CONFIG_EXECUTABLE})
1010   if(NETCDF_C_CONFIG_EXECUTABLE)
1011      NETCDF_CONFIG(--cc NETCDF_C_COMPILER_C)
1012      NETCDF_CONFIG(--fc NETCDF_C_COMPILER_FORTRAN)
1013      NETCDF_CONFIG(--prefix NETCDF_C_ROOT)
1014      NETCDF_CONFIG(--includedir NETCDF_C_INCLUDE)
1015      NETCDF_CONFIG(--version NETCDF_C_VERSION)
1016      #NETCDF_CONFIG(--has-c++ NETCDF_C_CXX)
1017      #NETCDF_CONFIG(--has-f77 NETCDF_C_F77)
1018      NETCDF_CONFIG(--has-f90 NETCDF_C_F90)
1019      #NETCDF_CONFIG(--has-dap NETCDF_C_DAP)
1020      #NETCDF_CONFIG(--has-nc2 NETCDF_C_NC2)
1021      #NETCDF_CONFIG(--has-nc4 NETCDF_C_NC4)
1022      #NETCDF_CONFIG(--has-hdf4 NETCDF_C_HDF4)
1023      #NETCDF_CONFIG(--has-hdf5 NETCDF_C_HDF5)
1024      #NETCDF_CONFIG(--has-pnetcdf NETCDF_C_PARALLEL)
1025      list(APPEND NETCDF_INCLUDE_HINTS "\${NETCDF_C_INCLUDE}")
1026      list(APPEND NETCDF_HINTS "\${NETCDF_C_ROOT}")
1027      message(STATUS "Found \${NETCDF_C_VERSION} compiled with \${NETCDF_C_COMPILER_C}")
1028   else(NETCDF_C_CONFIG_EXECUTABLE)
1029      message(STATUS "nc-config not found")
1030   endif(NETCDF_C_CONFIG_EXECUTABLE)
1031
1032if(NETCDF_C_ROOT AND NETCDF_FORTRAN_ROOT)
1033   find_program(NETCDF_FORTRAN_CONFIG_EXECUTABLE NAMES nf-config
1034       HINTS \${NETCDF_HINTS} PATH_SUFFIXES bin Bin NO_DEFAULT_PATH
1035       DOC "NETCDF CONFIG PROGRAM. Used to detect NETCDF compile flags." )
1036else()
1037   find_program(NETCDF_FORTRAN_CONFIG_EXECUTABLE NAMES nf-config
1038       HINTS \${NETCDF_HINTS} PATH_SUFFIXES bin Bin
1039       DOC "NETCDF CONFIG PROGRAM. Used to detect NETCDF compile flags." )
1040endif()
1041
1042set(NETCDF_CONFIG_EXECUTABLE \${NETCDF_FORTRAN_CONFIG_EXECUTABLE})
1043   if(NETCDF_FORTRAN_CONFIG_EXECUTABLE)
1044      NETCDF_CONFIG(--cc NETCDF_FORTRAN_COMPILER_C)
1045      NETCDF_CONFIG(--fc NETCDF_FORTRAN_COMPILER_FORTRAN)
1046      NETCDF_CONFIG(--prefix NETCDF_FORTRAN_ROOT)
1047      NETCDF_CONFIG(--includedir NETCDF_FORTRAN_INCLUDE)
1048      NETCDF_CONFIG(--version NETCDF_FORTRAN_VERSION)
1049      #NETCDF_CONFIG(--has-c++ NETCDF_FORTRAN_CXX)
1050      #NETCDF_CONFIG(--has-f77 NETCDF_FORTRAN_F77)
1051      NETCDF_CONFIG(--has-f90 NETCDF_FORTRAN_F90)
1052      #NETCDF_CONFIG(--has-dap NETCDF_FORTRAN_DAP)
1053      #NETCDF_CONFIG(--has-nc2 NETCDF_FORTRAN_NC2)
1054      #NETCDF_CONFIG(--has-nc4 NETCDF_FORTRAN_NC4)
1055      #NETCDF_CONFIG(--has-hdf4 NETCDF_FORTRAN_HDF4)
1056      #NETCDF_CONFIG(--has-hdf5 NETCDF_FORTRAN_HDF5)
1057      #NETCDF_CONFIG(--has-pnetcdf NETCDF_FORTRAN_PARALLEL)
1058      list(APPEND NETCDF_INCLUDE_HINTS "\${NETCDF_FORTRAN_INCLUDE}")
1059      list(APPEND NETCDF_HINTS "\${NETCDF_FORTRAN_ROOT}")
1060      message(STATUS "Found \${NETCDF_FORTRAN_VERSION} compiled with \${NETCDF_FORTRAN_COMPILER_FORTRAN}")
1061   else(NETCDF_FORTRAN_CONFIG_EXECUTABLE)
1062      #message(STATUS "nf-config not found")
1063      set(NETCDF_FORTRAN_COMPILER_C \${NETCDF_C_COMPILER_C})
1064      set(NETCDF_FORTRAN_COMPILER_FORTRAN \${NETCDF_C_COMPILER_FORTRAN})
1065      set(NETCDF_FORTRAN_ROOT \${NETCDF_C_ROOT})
1066      set(NETCDF_FORTRAN_INCLUDE \${NETCDF_C_INCLUDE})
1067      set(NETCDF_FORTRAN_VERSION \${NETCDF_C_VERSION})
1068      #set(NETCDF_FORTRAN_CXX \${NETCDF_C_CXX})
1069      #set(NETCDF_FORTRAN_F77 \${NETCDF_C_F77})
1070      set(NETCDF_FORTRAN_F90 \${NETCDF_C_F90})
1071      #set(NETCDF_FORTRAN_DAP \${NETCDF_C_DAP})
1072      #set(NETCDF_FORTRAN_NC2 \${NETCDF_C_NC2})
1073      #set(NETCDF_FORTRAN_NC4 \${NETCDF_C_NC4})
1074      #set(NETCDF_FORTRAN_HDF4 \${NETCDF_C_HDF4})
1075      #set(NETCDF_FORTRAN_HDF5 \${NETCDF_C_HDF5})
1076      #set(NETCDF_FORTRAN_PARALLEL \${NETCDF_C_PARALLEL})
1077      if(NETCDF_FORTRAN_F90)
1078         message(STATUS "Found \${NETCDF_FORTRAN_VERSION} compiled with \${NETCDF_FORTRAN_COMPILER_FORTRAN}")
1079      else(NETCDF_FORTRAN_F90)
1080         message(STATUS "nc-config found no netCDF Fortran libraries")
1081      endif(NETCDF_FORTRAN_F90)
1082   endif(NETCDF_FORTRAN_CONFIG_EXECUTABLE)
1083
1084# find netcdf c
1085if(NOT NETCDF_C_INCLUDE)
1086   find_path(NETCDF_C_INCLUDE netcdf.h HINTS \${NETCDF_HINTS} PATH_SUFFIXES include Include)
1087endif()
1088find_library(NETCDF_C_LIB netcdf HINTS \${NETCDF_HINTS} PATH_SUFFIXES lib lib64)
1089#message(STATUS "NETCDF_C_INCLUDE so far: \${NETCDF_C_INCLUDE}")
1090#message(STATUS "NETCDF_C_LIB so far: \${NETCDF_C_LIB}")
1091
1092# find netcdf fortran
1093if(NOT NETCDF_FORTRAN_INCLUDE)
1094   find_path(NETCDF_FORTRAN_INCLUDE netcdf.mod HINTS \${NETCDF_HINTS} PATH_SUFFIXES include Include)
1095endif()
1096find_library(NETCDF_FORTRAN_LIB netcdff HINTS \${NETCDF_HINTS} PATH_SUFFIXES lib lib64)
1097if(NOT NETCDF_FORTRAN_LIB)
1098   find_library(NETCDF_FORTRAN_LIB netcdf HINTS \${NETCDF_HINTS} PATH_SUFFIXES lib lib64)
1099endif()
1100#message(STATUS "NETCDF_FORTRAN_INCLUDE so far: \${NETCDF_FORTRAN_INCLUDE}")
1101#message(STATUS "NETCDF_FORTRAN_LIB so far: \${NETCDF_FORTRAN_LIB}")
1102
1103if ((NOT NETCDF_C_LIB) OR (NOT NETCDF_C_INCLUDE))
1104   message(STATUS "Trying to find NetCDF using LD_LIBRARY_PATH (we're desperate)...")
1105   file(TO_CMAKE_PATH "\$ENV{LD_LIBRARY_PATH}" LD_LIBRARY_PATH)
1106   find_library(NETCDF_C_LIB NAMES netcdf HINTS \${LD_LIBRARY_PATH})
1107
1108   if (NETCDF_C_LIB)
1109      get_filename_component(NETCDF_LIB_DIR \${NETCDF_C_LIB} PATH)
1110      string(REGEX REPLACE "/lib/?\$" "/include" NETCDF_H_HINT \${NETCDF_LIB_DIR})
1111      find_path (NETCDF_C_INCLUDE netcdf.h HINTS \${NETCDF_H_HINT} DOC "Path to netcdf.h")
1112      message(STATUS "found netcdf.h in: \${NETCDF_C_INCLUDE}")
1113      list(APPEND NETCDF_INCLUDE_HINTS "\${NETCDF_C_INCLUDE}")
1114   endif()
1115endif()
1116
1117get_filename_component (NETCDF_C_LIB_DIR "\${NETCDF_C_LIB}" PATH)
1118get_filename_component (NETCDF_FORTRAN_LIB_DIR "\${NETCDF_FORTRAN_LIB}" PATH)
1119list(APPEND NETCDF_LIB_HINTS "\${NETCDF_C_LIB_DIR}")
1120list(APPEND NETCDF_LIB_HINTS "\${NETCDF_FORTRAN_LIB_DIR}")
1121
1122#message(STATUS "All include Hints: \${NETCDF_INCLUDE_HINTS}")
1123#message(STATUS "All lib Hints: \${NETCDF_LIB_HINTS}")
1124
1125macro(NetCDF_add_interface lang)
1126   if(NETCDF_\${lang})
1127      if(NETCDF_\${lang}_INCLUDE AND NETCDF_\${lang}_LIB)
1128         list(INSERT NetCDF_includes 0 \${NETCDF_\${lang}_INCLUDE})
1129         list(INSERT NetCDF_libs 0 \${NETCDF_\${lang}_LIB}) # prepend so that -lnetcdf is last
1130      else()
1131         set(NetCDF_has_interfaces "NO")
1132         message(STATUS "Failed to find NetCDF interface for \${lang}")
1133      endif()
1134   endif(NETCDF_\${lang})
1135endmacro(NetCDF_add_interface)
1136
1137set(NetCDF_has_interfaces "YES") # will be set to NO if we're missing any interfaces
1138NetCDF_add_interface(C)
1139NetCDF_add_interface(CXX)
1140NetCDF_add_interface(FORTRAN)
1141
1142# macro (NetCDF_check_interface lang header libs)
1143#    if (NETCDF_\${lang})
1144#       find_path (NETCDF_INCLUDES_\${lang} NAMES \${header} HINTS \${NETCDF_HINTS} PATH_SUFFIXES include Include NO_DEFAULT_PATH)
1145#       find_library (NETCDF_LIBRARIES_\${lang} NAMES \${libs} HINTS \${NETCDF_HINTS} PATH_SUFFIXES lib lib64 NO_DEFAULT_PATH)
1146#       mark_as_advanced (NETCDF_INCLUDES_\${lang} NETCDF_LIBRARIES_\${lang})
1147#       if (NETCDF_INCLUDES_\${lang} AND NETCDF_LIBRARIES_\${lang})
1148#          list (INSERT NetCDF_libs 0 \${NETCDF_LIBRARIES_\${lang}}) # prepend so that -lnetcdf is last
1149#       else (NETCDF_INCLUDES_\${lang} AND NETCDF_LIBRARIES_\${lang})
1150#          set (NetCDF_has_interfaces "NO")
1151#          message (STATUS "Failed to find NetCDF interface for \${lang}")
1152#       endif (NETCDF_INCLUDES_\${lang} AND NETCDF_LIBRARIES_\${lang})
1153#    endif (NETCDF_\${lang})
1154# endmacro (NetCDF_check_interface)
1155#
1156# set (NetCDF_has_interfaces "YES") # will be set to NO if we're missing any interfaces
1157# NetCDF_check_interface (C netcdf.h netcdf)
1158# NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++)
1159# NetCDF_check_interface (FORTRAN netcdf.mod  netcdff)
1160
1161set (NETCDF_C_COMPILER "\${NETCDF_C_COMPILER_C}" CACHE STRING "The C compiler used to build netCDF")
1162set (NETCDF_FORTRAN_COMPILER "\${NETCDF_FORTRAN_COMPILER_FORTRAN}" CACHE STRING "The Fortran compiler used to build netCDF")
1163set (NETCDF_INCLUDES "\${NetCDF_includes}" CACHE STRING "All NetCDF includes required for interface level")
1164set (NETCDF_LIBRARIES "\${NetCDF_libs}" CACHE STRING "All NetCDF libraries required for interface level")
1165
1166# handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if
1167# all listed variables are TRUE
1168include (FindPackageHandleStandardArgs)
1169find_package_handle_standard_args (NetCDF DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDES NetCDF_has_interfaces)
1170
1171mark_as_advanced (NETCDF_LIBRARIES NETCDF_INCLUDES)
1172
1173#message(STATUS "netCDF library: \${NETCDF_LIBRARIES}")
1174#message(STATUS "netCDF include: \${NETCDF_INCLUDES}")
1175
1176EOF
1177}
1178
1179################################################################################
1180
1181palm_installer_startup_message
1182palm_installer_update
1183
1184if [[ "${1}" =~ "--help" ]]; then
1185   palm_installer_help
1186fi
1187
1188if [[ "${1}" =~ "--version" ]]; then
1189   palm_installer_version
1190fi
1191
1192if [[ "${1}" =~ "--prep" ]]; then
1193   palm_installer_prep_mpi
1194   palm_installer_prep_netcdf
1195   palm_installer_prep_gt
1196   palm_installer_prep_fftw
1197   palm_installer_shutdown_message
1198fi
1199
1200palm_installer_check_software_all
1201palm_installer_init
1202palm_installer_build
1203palm_installer_set_path
1204palm_installer_test_suite
1205palm_post_installer_help
1206palm_installer_shutdown_message