"""Generate Fortran WENO kernels with PyWENO."""

# Copyright (c) 2011, Matthew Emmett.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#   1. Redistributions of source code must retain the above copyright
#      notice, this list of conditions and the following disclaimer.
#
#   2. Redistributions in binary form must reproduce the above
#      copyright notice, this list of conditions and the following
#      disclaimer in the documentation and/or other materials provided
#      with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import pyweno.symbolic
import pyweno.kernels
import pyweno.functions

import numpy as np

wrapper = pyweno.functions.FunctionGenerator('fortran')

#### set fortran templatese to match clawpack

pyweno.functions.templates['fortran']['callable'] = '''
subroutine {function}(q, ql, qr, num_eqn, maxnx, num_ghost)

  implicit none

  integer,          intent(in)  :: num_eqn, maxnx, num_ghost
  double precision, intent(in)  :: q(num_eqn,maxnx+2*num_ghost)
  double precision, intent(out) :: ql(num_eqn,maxnx+2*num_ghost), qr(num_eqn,maxnx+2*num_ghost)

  integer :: i, m
  double precision :: {variables}

  do i = num_ghost, maxnx+num_ghost+1
    do m = 1, num_eqn
      {kernel}
    end do
  end do

end subroutine
'''
pyweno.kernels.global_names['fortran'] = 'q(m,i{r:+d})'


#### open weno.f90 and write header

out = open('weno.f90', 'w')
out.write('''! This file was generated by: python weno.py
module weno
contains
''')


#### generate and write reconstruction functions

for k in range(3, 10):
# for k in range(3, 5):

  print 'generating reconstruction for k: %02d' % k
  
  # set smoothness
  beta = pyweno.symbolic.jiang_shu_smoothness_coefficients(k)
  wrapper.set_smoothness(beta)

  # reconstructions: -1=left, 1=right
  (varpi, split) = pyweno.symbolic.optimal_weights(k, [ -1, 1 ])
  coeffs = pyweno.symbolic.reconstruction_coefficients(k, [ -1, 1 ])

  wrapper.set_optimal_weights(varpi, split)
  wrapper.set_reconstruction_coefficients(coeffs)

  # tweak reconstructed function (f_star) names to match subroutine
  # definition above
  wrapper.global_f_star[0] = 'ql(m,i)'
  wrapper.global_f_star[1] = 'qr(m,i)'
  
  # write function
  out.write(wrapper.generate(
    function='weno%d' % (2*k-1), normalise=False))


#### done

out.write('''end module weno''')
out.close()
