Index: /issm/trunk-jpl/externalpackages/autotools/install-debian-linux.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/autotools/install-debian-linux.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/autotools/install-debian-linux.sh	(revision 24593)
@@ -0,0 +1,71 @@
+#!/bin/bash
+set -eu
+
+#Version numbers
+M4_VER="1.4.18"
+AUTOCONF_VER="2.69"
+AUTOMAKE_VER="1.16.1"
+LIBTOOL_VER="2.4.2"
+
+# Clean up existing directories
+rm -rf install src
+
+# Set up for installation
+mkdir install
+export PATH="$ISSM_DIR/externalpackages/autotools/install/bin:$PATH"
+
+# Install m4
+echo " === INSTALLING M4 =="
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/m4-$M4_VER.tar.gz" "m4-$M4_VER.tar.gz"
+tar -zxvf m4-$M4_VER.tar.gz
+mv m4-$M4_VER src
+cd src
+
+## Fixes required by glibc-2.28
+#
+# Source: http://www.linuxfromscratch.org/lfs/view/development/chapter06/m4.html
+#
+sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
+echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
+
+./configure --prefix="$ISSM_DIR/externalpackages/autotools/install"
+make
+make install
+cd ..
+
+# Install autoconf
+echo " === INSTALLING AUTOCONF =="
+rm -rf src
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/autoconf-$AUTOCONF_VER.tar.gz" "autoconf-$AUTOCONF_VER.tar.gz"
+tar -zxvf autoconf-$AUTOCONF_VER.tar.gz
+mv autoconf-$AUTOCONF_VER src
+cd src
+./configure --prefix="$ISSM_DIR/externalpackages/autotools/install"
+make
+make install
+cd ..
+
+#install automake
+echo " === INSTALLING AUTOMAKE =="
+rm -rf src
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/automake-$AUTOMAKE_VER.tar.gz" "automake-$AUTOMAKE_VER.tar.gz"
+tar -zxvf  automake-$AUTOMAKE_VER.tar.gz
+mv automake-$AUTOMAKE_VER src
+cd src
+./configure --prefix="$ISSM_DIR/externalpackages/autotools/install"
+make
+make install
+cd ..
+
+# Install libtool
+echo " === INSTALLING LIBTOOL =="
+rm -rf src
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/libtool-$LIBTOOL_VER.tar.gz" "libtool-$LIBTOOL_VER.tar.gz"
+tar -zxvf  libtool-$LIBTOOL_VER.tar.gz
+rm libtool-$LIBTOOL_VER.tar.gz
+mv libtool-$LIBTOOL_VER src
+cd src
+./configure --prefix="$ISSM_DIR/externalpackages/autotools/install"
+make
+make install
+cd ..
Index: /issm/trunk-jpl/externalpackages/boost/configs/1.55/linux/boost/multi_index/ordered_index.hpp
===================================================================
--- /issm/trunk-jpl/externalpackages/boost/configs/1.55/linux/boost/multi_index/ordered_index.hpp	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/boost/configs/1.55/linux/boost/multi_index/ordered_index.hpp	(revision 24593)
@@ -0,0 +1,1529 @@
+/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ *
+ * The internal implementation of red-black trees is based on that of SGI STL
+ * stl_tree.h file:
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP
+#define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/call_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/foreach_fwd.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/move/core.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/push_front.hpp>
+#include <boost/multi_index/detail/access_specifier.hpp>
+#include <boost/multi_index/detail/bidir_node_iterator.hpp>
+#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
+#include <boost/multi_index/detail/index_node_base.hpp>
+#include <boost/multi_index/detail/modify_key_adaptor.hpp>
+#include <boost/multi_index/detail/ord_index_node.hpp>
+#include <boost/multi_index/detail/ord_index_ops.hpp>
+#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
+#include <boost/multi_index/detail/safe_mode.hpp>
+#include <boost/multi_index/detail/scope_guard.hpp>
+#include <boost/multi_index/detail/unbounded.hpp>
+#include <boost/multi_index/detail/value_compare.hpp>
+#include <boost/multi_index/detail/vartempl_support.hpp>
+#include <boost/multi_index/ordered_index_fwd.hpp>
+#include <boost/ref.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <utility>
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+#include <boost/archive/archive_exception.hpp>
+#include <boost/bind.hpp>
+#include <boost/multi_index/detail/duplicates_iterator.hpp>
+#include <boost/throw_exception.hpp>
+#endif
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)                    \
+  detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)=                 \
+    detail::make_obj_guard(x,&ordered_index::check_invariant_);              \
+  BOOST_JOIN(check_invariant_,__LINE__).touch();
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT                          \
+  BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
+#else
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
+#endif
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* ordered_index adds a layer of ordered indexing to a given Super */
+
+/* Most of the implementation of unique and non-unique indices is
+ * shared. We tell from one another on instantiation time by using
+ * these tags.
+ */
+
+struct ordered_unique_tag{};
+struct ordered_non_unique_tag{};
+
+template<
+  typename KeyFromValue,typename Compare,
+  typename SuperMeta,typename TagList,typename Category
+>
+class ordered_index:
+  BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
+  ,public safe_ctr_proxy_impl<
+    bidir_node_iterator<
+      ordered_index_node<typename SuperMeta::type::node_type> >,
+    ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category> >
+#else
+  ,public safe_mode::safe_container<
+    ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category> >
+#endif
+#endif
+
+{
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
+    BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
+ * lifetime of const references bound to temporaries --precisely what
+ * scopeguards are.
+ */
+
+#pragma parse_mfunc_templ off
+#endif
+
+  typedef typename SuperMeta::type                   super;
+
+protected:
+  typedef ordered_index_node<
+    typename super::node_type>                       node_type;
+
+private:
+  typedef typename node_type::impl_type              node_impl_type;
+  typedef typename node_impl_type::pointer           node_impl_pointer;
+
+public:
+  /* types */
+
+  typedef typename KeyFromValue::result_type         key_type;
+  typedef typename node_type::value_type             value_type;
+  typedef KeyFromValue                               key_from_value;
+  typedef Compare                                    key_compare;
+  typedef value_comparison<
+    value_type,KeyFromValue,Compare>                 value_compare;
+  typedef tuple<key_from_value,key_compare>          ctor_args;
+  typedef typename super::final_allocator_type       allocator_type;
+  typedef typename allocator_type::reference         reference;
+  typedef typename allocator_type::const_reference   const_reference;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
+  typedef safe_mode::safe_iterator<
+    bidir_node_iterator<node_type>,
+    safe_ctr_proxy<
+      bidir_node_iterator<node_type> > >             iterator;
+#else
+  typedef safe_mode::safe_iterator<
+    bidir_node_iterator<node_type>,
+    ordered_index>                                   iterator;
+#endif
+#else
+  typedef bidir_node_iterator<node_type>             iterator;
+#endif
+
+  typedef iterator                                   const_iterator;
+
+  typedef std::size_t                                size_type;
+  typedef std::ptrdiff_t                             difference_type;
+  typedef typename allocator_type::pointer           pointer;
+  typedef typename allocator_type::const_pointer     const_pointer;
+  typedef typename
+    boost::reverse_iterator<iterator>                reverse_iterator;
+  typedef typename
+    boost::reverse_iterator<const_iterator>          const_reverse_iterator;
+  typedef TagList                                    tag_list;
+
+protected:
+  typedef typename super::final_node_type            final_node_type;
+  typedef tuples::cons<
+    ctor_args,
+    typename super::ctor_args_list>                  ctor_args_list;
+  typedef typename mpl::push_front<
+    typename super::index_type_list,
+    ordered_index>::type                             index_type_list;
+  typedef typename mpl::push_front<
+    typename super::iterator_type_list,
+    iterator>::type    iterator_type_list;
+  typedef typename mpl::push_front<
+    typename super::const_iterator_type_list,
+    const_iterator>::type                            const_iterator_type_list;
+  typedef typename super::copy_map_type              copy_map_type;
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+  typedef typename super::index_saver_type           index_saver_type;
+  typedef typename super::index_loader_type          index_loader_type;
+#endif
+
+private:
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
+  typedef safe_ctr_proxy_impl<
+    bidir_node_iterator<node_type>,
+    ordered_index>                                   safe_super;
+#else
+  typedef safe_mode::safe_container<ordered_index>   safe_super;
+#endif
+#endif
+
+  typedef typename call_traits<
+    value_type>::param_type                          value_param_type;
+  typedef typename call_traits<
+    key_type>::param_type                            key_param_type;
+
+  /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
+   * expansion.
+   */
+
+  typedef std::pair<iterator,bool>                   emplace_return_type;
+
+public:
+
+  /* construct/copy/destroy
+   * Default and copy ctors are in the protected section as indices are
+   * not supposed to be created on their own. No range ctor either.
+   */
+
+  ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
+    const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
+  {
+    this->final()=x.final();
+    return *this;
+  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+  ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
+    std::initializer_list<value_type> list)
+  {
+    this->final()=list;
+    return *this;
+  }
+#endif
+
+  allocator_type get_allocator()const
+  {
+    return this->final().get_allocator();
+  }
+
+  /* iterators */
+
+  iterator               begin(){return make_iterator(leftmost());}
+  const_iterator         begin()const{return make_iterator(leftmost());}
+  iterator               end(){return make_iterator(header());}
+  const_iterator         end()const{return make_iterator(header());}
+  reverse_iterator       rbegin(){return boost::make_reverse_iterator(end());}
+  const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
+  reverse_iterator       rend(){return make_reverse_iterator(begin());}
+  const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
+  const_iterator         cbegin()const{return begin();}
+  const_iterator         cend()const{return end();}
+  const_reverse_iterator crbegin()const{return rbegin();}
+  const_reverse_iterator crend()const{return rend();}
+
+  iterator iterator_to(const value_type& x)
+  {
+    return make_iterator(node_from_value<node_type>(&x));
+  }
+
+  const_iterator iterator_to(const value_type& x)const
+  {
+    return make_iterator(node_from_value<node_type>(&x));
+  }
+
+  /* capacity */
+
+  bool      empty()const{return this->final_empty_();}
+  size_type size()const{return this->final_size_();}
+  size_type max_size()const{return this->final_max_size_();}
+
+  /* modifiers */
+
+  BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
+    emplace_return_type,emplace,emplace_impl)
+
+  BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
+    iterator,emplace_hint,emplace_hint_impl,iterator,position)
+
+  std::pair<iterator,bool> insert(const value_type& x)
+  {
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    std::pair<final_node_type*,bool> p=this->final_insert_(x);
+    return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+  }
+
+  std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+  {
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
+    return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+  }
+
+  iterator insert(iterator position,const value_type& x)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    std::pair<final_node_type*,bool> p=this->final_insert_(
+      x,static_cast<final_node_type*>(position.get_node()));
+    return make_iterator(p.first);
+  }
+
+  iterator insert(iterator position,BOOST_RV_REF(value_type) x)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    std::pair<final_node_type*,bool> p=this->final_insert_rv_(
+      x,static_cast<final_node_type*>(position.get_node()));
+    return make_iterator(p.first);
+  }
+
+  template<typename InputIterator>
+  void insert(InputIterator first,InputIterator last)
+  {
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    node_type* hint=header(); /* end() */
+    for(;first!=last;++first){
+      hint=this->final_insert_ref_(
+        *first,static_cast<final_node_type*>(hint)).first;
+      node_type::increment(hint);
+    }
+  }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+  void insert(std::initializer_list<value_type> list)
+  {
+    insert(list.begin(),list.end());
+  }
+#endif
+
+  iterator erase(iterator position)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
+    return position;
+  }
+
+  size_type erase(key_param_type x)
+  {
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    std::pair<iterator,iterator> p=equal_range(x);
+    size_type s=0;
+    while(p.first!=p.second){
+      p.first=erase(p.first);
+      ++s;
+    }
+    return s;
+  }
+
+  iterator erase(iterator first,iterator last)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
+    BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    while(first!=last){
+      first=erase(first);
+    }
+    return first;
+  }
+
+  bool replace(iterator position,const value_type& x)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    return this->final_replace_(
+      x,static_cast<final_node_type*>(position.get_node()));
+  }
+
+  bool replace(iterator position,BOOST_RV_REF(value_type) x)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    return this->final_replace_rv_(
+      x,static_cast<final_node_type*>(position.get_node()));
+  }
+
+  template<typename Modifier>
+  bool modify(iterator position,Modifier mod)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    /* MSVC++ 6.0 optimizer on safe mode code chokes if this
+     * this is not added. Left it for all compilers as it does no
+     * harm.
+     */
+
+    position.detach();
+#endif
+
+    return this->final_modify_(
+      mod,static_cast<final_node_type*>(position.get_node()));
+  }
+
+  template<typename Modifier,typename Rollback>
+  bool modify(iterator position,Modifier mod,Rollback back)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    /* MSVC++ 6.0 optimizer on safe mode code chokes if this
+     * this is not added. Left it for all compilers as it does no
+     * harm.
+     */
+
+    position.detach();
+#endif
+
+    return this->final_modify_(
+      mod,back,static_cast<final_node_type*>(position.get_node()));
+  }
+
+  template<typename Modifier>
+  bool modify_key(iterator position,Modifier mod)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    return modify(
+      position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
+  }
+
+  template<typename Modifier,typename Rollback>
+  bool modify_key(iterator position,Modifier mod,Rollback back)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    return modify(
+      position,
+      modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
+      modify_key_adaptor<Rollback,value_type,KeyFromValue>(back,key));
+  }
+
+  void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
+  {
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
+    this->final_swap_(x.final());
+  }
+
+  void clear()
+  {
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    this->final_clear_();
+  }
+
+  /* observers */
+
+  key_from_value key_extractor()const{return key;}
+  key_compare    key_comp()const{return comp_;}
+  value_compare  value_comp()const{return value_compare(key,comp_);}
+
+  /* set operations */
+
+  /* Internally, these ops rely on const_iterator being the same
+   * type as iterator.
+   */
+
+  template<typename CompatibleKey>
+  iterator find(const CompatibleKey& x)const
+  {
+    return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
+  }
+
+  template<typename CompatibleKey,typename CompatibleCompare>
+  iterator find(
+    const CompatibleKey& x,const CompatibleCompare& comp)const
+  {
+    return make_iterator(ordered_index_find(root(),header(),key,x,comp));
+  }
+
+  template<typename CompatibleKey>
+  size_type count(const CompatibleKey& x)const
+  {
+    return count(x,comp_);
+  }
+
+  template<typename CompatibleKey,typename CompatibleCompare>
+  size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
+  {
+    std::pair<iterator,iterator> p=equal_range(x,comp);
+    size_type n=std::distance(p.first,p.second);
+    return n;
+  }
+
+  template<typename CompatibleKey>
+  iterator lower_bound(const CompatibleKey& x)const
+  {
+    return make_iterator(
+      ordered_index_lower_bound(root(),header(),key,x,comp_));
+  }
+
+  template<typename CompatibleKey,typename CompatibleCompare>
+  iterator lower_bound(
+    const CompatibleKey& x,const CompatibleCompare& comp)const
+  {
+    return make_iterator(
+      ordered_index_lower_bound(root(),header(),key,x,comp));
+  }
+
+  template<typename CompatibleKey>
+  iterator upper_bound(const CompatibleKey& x)const
+  {
+    return make_iterator(
+      ordered_index_upper_bound(root(),header(),key,x,comp_));
+  }
+
+  template<typename CompatibleKey,typename CompatibleCompare>
+  iterator upper_bound(
+    const CompatibleKey& x,const CompatibleCompare& comp)const
+  {
+    return make_iterator(
+      ordered_index_upper_bound(root(),header(),key,x,comp));
+  }
+
+  template<typename CompatibleKey>
+  std::pair<iterator,iterator> equal_range(
+    const CompatibleKey& x)const
+  {
+    std::pair<node_type*,node_type*> p=
+      ordered_index_equal_range(root(),header(),key,x,comp_);
+    return std::pair<iterator,iterator>(
+      make_iterator(p.first),make_iterator(p.second));
+  }
+
+  template<typename CompatibleKey,typename CompatibleCompare>
+  std::pair<iterator,iterator> equal_range(
+    const CompatibleKey& x,const CompatibleCompare& comp)const
+  {
+    std::pair<node_type*,node_type*> p=
+      ordered_index_equal_range(root(),header(),key,x,comp);
+    return std::pair<iterator,iterator>(
+      make_iterator(p.first),make_iterator(p.second));
+  }
+
+  /* range */
+
+  template<typename LowerBounder,typename UpperBounder>
+  std::pair<iterator,iterator>
+  range(LowerBounder lower,UpperBounder upper)const
+  {
+    typedef typename mpl::if_<
+      is_same<LowerBounder,unbounded_type>,
+      BOOST_DEDUCED_TYPENAME mpl::if_<
+        is_same<UpperBounder,unbounded_type>,
+        both_unbounded_tag,
+        lower_unbounded_tag
+      >::type,
+      BOOST_DEDUCED_TYPENAME mpl::if_<
+        is_same<UpperBounder,unbounded_type>,
+        upper_unbounded_tag,
+        none_unbounded_tag
+      >::type
+    >::type dispatch;
+
+    return range(lower,upper,dispatch());
+  }
+
+BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
+  ordered_index(const ctor_args_list& args_list,const allocator_type& al):
+    super(args_list.get_tail(),al),
+    key(tuples::get<0>(args_list.get_head())),
+    comp_(tuples::get<1>(args_list.get_head()))
+  {
+    empty_initialize();
+  }
+
+  ordered_index(
+    const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x):
+    super(x),
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    safe_super(),
+#endif
+
+    key(x.key),
+    comp_(x.comp_)
+  {
+    /* Copy ctor just takes the key and compare objects from x. The rest is
+     * done in a subsequent call to copy_().
+     */
+  }
+
+  ordered_index(
+     const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
+     do_not_copy_elements_tag):
+    super(x,do_not_copy_elements_tag()),
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    safe_super(),
+#endif
+
+    key(x.key),
+    comp_(x.comp_)
+  {
+    empty_initialize();
+  }
+
+  ~ordered_index()
+  {
+    /* the container is guaranteed to be empty by now */
+  }
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+  iterator       make_iterator(node_type* node){return iterator(node,this);}
+  const_iterator make_iterator(node_type* node)const
+    {return const_iterator(node,const_cast<ordered_index*>(this));}
+#else
+  iterator       make_iterator(node_type* node){return iterator(node);}
+  const_iterator make_iterator(node_type* node)const
+                   {return const_iterator(node);}
+#endif
+
+  void copy_(
+    const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
+    const copy_map_type& map)
+  {
+    if(!x.root()){
+      empty_initialize();
+    }
+    else{
+      header()->color()=x.header()->color();
+
+      node_type* root_cpy=map.find(static_cast<final_node_type*>(x.root()));
+      header()->parent()=root_cpy->impl();
+
+      node_type* leftmost_cpy=map.find(
+        static_cast<final_node_type*>(x.leftmost()));
+      header()->left()=leftmost_cpy->impl();
+
+      node_type* rightmost_cpy=map.find(
+        static_cast<final_node_type*>(x.rightmost()));
+      header()->right()=rightmost_cpy->impl();
+
+      typedef typename copy_map_type::const_iterator copy_map_iterator;
+      for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
+        node_type* org=it->first;
+        node_type* cpy=it->second;
+
+        cpy->color()=org->color();
+
+        node_impl_pointer parent_org=org->parent();
+        if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
+        else{
+          node_type* parent_cpy=map.find(
+            static_cast<final_node_type*>(node_type::from_impl(parent_org)));
+          cpy->parent()=parent_cpy->impl();
+          if(parent_org->left()==org->impl()){
+            parent_cpy->left()=cpy->impl();
+          }
+          else if(parent_org->right()==org->impl()){
+            /* header() does not satisfy this nor the previous check */
+            parent_cpy->right()=cpy->impl();
+          }
+        }
+
+        if(org->left()==node_impl_pointer(0))
+          cpy->left()=node_impl_pointer(0);
+        if(org->right()==node_impl_pointer(0))
+          cpy->right()=node_impl_pointer(0);
+      }
+    }
+
+    super::copy_(x,map);
+  }
+
+  template<typename Variant>
+  node_type* insert_(value_param_type v,node_type* x,Variant variant)
+  {
+    link_info inf;
+    if(!link_point(key(v),inf,Category())){
+      return node_type::from_impl(inf.pos);
+    }
+
+    node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
+    if(res==x){
+      node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+    }
+    return res;
+  }
+
+  template<typename Variant>
+  node_type* insert_(
+    value_param_type v,node_type* position,node_type* x,Variant variant)
+  {
+    link_info inf;
+    if(!hinted_link_point(key(v),position,inf,Category())){
+      return node_type::from_impl(inf.pos);
+    }
+
+    node_type* res=static_cast<node_type*>(super::insert_(v,position,x,variant));
+    if(res==x){
+      node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+    }
+    return res;
+  }
+
+  void erase_(node_type* x)
+  {
+    node_impl_type::rebalance_for_erase(
+      x->impl(),header()->parent(),header()->left(),header()->right());
+    super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    detach_iterators(x);
+#endif
+  }
+
+  void delete_all_nodes_()
+  {
+    delete_all_nodes(root());
+  }
+
+  void clear_()
+  {
+    super::clear_();
+    empty_initialize();
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    safe_super::detach_dereferenceable_iterators();
+#endif
+  }
+
+  void swap_(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
+  {
+    std::swap(key,x.key);
+    std::swap(comp_,x.comp_);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    safe_super::swap(x);
+#endif
+
+    super::swap_(x);
+  }
+
+  void swap_elements_(
+    ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
+  {
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+    safe_super::swap(x);
+#endif
+
+    super::swap_elements_(x);
+  }
+
+  template<typename Variant>
+  bool replace_(value_param_type v,node_type* x,Variant variant)
+  {
+    if(in_place(v,x,Category())){
+      return super::replace_(v,x,variant);
+    }
+
+    node_type* next=x;
+    node_type::increment(next);
+
+    node_impl_type::rebalance_for_erase(
+      x->impl(),header()->parent(),header()->left(),header()->right());
+
+    BOOST_TRY{
+      link_info inf;
+      if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
+        node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+        return true;
+      }
+      node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+      return false;
+    }
+    BOOST_CATCH(...){
+      node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+      BOOST_RETHROW;
+    }
+    BOOST_CATCH_END
+  }
+
+  bool modify_(node_type* x)
+  {
+    bool b;
+    BOOST_TRY{
+      b=in_place(x->value(),x,Category());
+    }
+    BOOST_CATCH(...){
+      erase_(x);
+      BOOST_RETHROW;
+    }
+    BOOST_CATCH_END
+    if(!b){
+      node_impl_type::rebalance_for_erase(
+        x->impl(),header()->parent(),header()->left(),header()->right());
+      BOOST_TRY{
+        link_info inf;
+        if(!link_point(key(x->value()),inf,Category())){
+          super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+          detach_iterators(x);
+#endif
+          return false;
+        }
+        node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+      }
+      BOOST_CATCH(...){
+        super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+        detach_iterators(x);
+#endif
+
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+    }
+
+    BOOST_TRY{
+      if(!super::modify_(x)){
+        node_impl_type::rebalance_for_erase(
+          x->impl(),header()->parent(),header()->left(),header()->right());
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+        detach_iterators(x);
+#endif
+
+        return false;
+      }
+      else return true;
+    }
+    BOOST_CATCH(...){
+      node_impl_type::rebalance_for_erase(
+        x->impl(),header()->parent(),header()->left(),header()->right());
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+      detach_iterators(x);
+#endif
+
+      BOOST_RETHROW;
+    }
+    BOOST_CATCH_END
+  }
+
+  bool modify_rollback_(node_type* x)
+  {
+    if(in_place(x->value(),x,Category())){
+      return super::modify_rollback_(x);
+    }
+
+    node_type* next=x;
+    node_type::increment(next);
+
+    node_impl_type::rebalance_for_erase(
+      x->impl(),header()->parent(),header()->left(),header()->right());
+
+    BOOST_TRY{
+      link_info inf;
+      if(link_point(key(x->value()),inf,Category())&&
+         super::modify_rollback_(x)){
+        node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+        return true;
+      }
+      node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+      return false;
+    }
+    BOOST_CATCH(...){
+      node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+      BOOST_RETHROW;
+    }
+    BOOST_CATCH_END
+  }
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+  /* serialization */
+
+  template<typename Archive>
+  void save_(
+    Archive& ar,const unsigned int version,const index_saver_type& sm)const
+  {
+    save_(ar,version,sm,Category());
+  }
+
+  template<typename Archive>
+  void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
+  {
+    load_(ar,version,lm,Category());
+  }
+#endif
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
+  /* invariant stuff */
+
+  bool invariant_()const
+  {
+    if(size()==0||begin()==end()){
+      if(size()!=0||begin()!=end()||
+         header()->left()!=header()->impl()||
+         header()->right()!=header()->impl())return false;
+    }
+    else{
+      if((size_type)std::distance(begin(),end())!=size())return false;
+
+      std::size_t len=node_impl_type::black_count(
+        leftmost()->impl(),root()->impl());
+      for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
+        node_type* x=it.get_node();
+        node_type* left_x=node_type::from_impl(x->left());
+        node_type* right_x=node_type::from_impl(x->right());
+
+        if(x->color()==red){
+          if((left_x&&left_x->color()==red)||
+             (right_x&&right_x->color()==red))return false;
+        }
+        if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
+        if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
+        if(!left_x&&!right_x&&
+           node_impl_type::black_count(x->impl(),root()->impl())!=len)
+          return false;
+      }
+
+      if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
+        return false;
+      if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
+        return false;
+    }
+
+    return super::invariant_();
+  }
+
+
+  /* This forwarding function eases things for the boost::mem_fn construct
+   * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually,
+   * final_check_invariant is already an inherited member function of
+   * ordered_index.
+   */
+  void check_invariant_()const{this->final_check_invariant_();}
+#endif
+
+private:
+  node_type* header()const{return this->final_header();}
+  node_type* root()const{return node_type::from_impl(header()->parent());}
+  node_type* leftmost()const{return node_type::from_impl(header()->left());}
+  node_type* rightmost()const{return node_type::from_impl(header()->right());}
+
+  void empty_initialize()
+  {
+    header()->color()=red;
+    /* used to distinguish header() from root, in iterator.operator++ */
+
+    header()->parent()=node_impl_pointer(0);
+    header()->left()=header()->impl();
+    header()->right()=header()->impl();
+  }
+
+  struct link_info
+  {
+    link_info():side(to_left){}
+
+    ordered_index_side side;
+    node_impl_pointer  pos;
+  };
+
+  bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
+  {
+    node_type* y=header();
+    node_type* x=root();
+    bool c=true;
+    while(x){
+      y=x;
+      c=comp_(k,key(x->value()));
+      x=node_type::from_impl(c?x->left():x->right());
+    }
+    node_type* yy=y;
+    if(c){
+      if(yy==leftmost()){
+        inf.side=to_left;
+        inf.pos=y->impl();
+        return true;
+      }
+      else node_type::decrement(yy);
+    }
+
+    if(comp_(key(yy->value()),k)){
+      inf.side=c?to_left:to_right;
+      inf.pos=y->impl();
+      return true;
+    }
+    else{
+      inf.pos=yy->impl();
+      return false;
+    }
+  }
+
+  bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
+  {
+    node_type* y=header();
+    node_type* x=root();
+    bool c=true;
+    while (x){
+     y=x;
+     c=comp_(k,key(x->value()));
+     x=node_type::from_impl(c?x->left():x->right());
+    }
+    inf.side=c?to_left:to_right;
+    inf.pos=y->impl();
+    return true;
+  }
+
+  bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
+  {
+    node_type* y=header();
+    node_type* x=root();
+    bool c=false;
+    while (x){
+     y=x;
+     c=comp_(key(x->value()),k);
+     x=node_type::from_impl(c?x->right():x->left());
+    }
+    inf.side=c?to_right:to_left;
+    inf.pos=y->impl();
+    return true;
+  }
+
+  bool hinted_link_point(
+    key_param_type k,node_type* position,link_info& inf,ordered_unique_tag)
+  {
+    if(position->impl()==header()->left()){
+      if(size()>0&&comp_(k,key(position->value()))){
+        inf.side=to_left;
+        inf.pos=position->impl();
+        return true;
+      }
+      else return link_point(k,inf,ordered_unique_tag());
+    }
+    else if(position==header()){
+      if(comp_(key(rightmost()->value()),k)){
+        inf.side=to_right;
+        inf.pos=rightmost()->impl();
+        return true;
+      }
+      else return link_point(k,inf,ordered_unique_tag());
+    }
+    else{
+      node_type* before=position;
+      node_type::decrement(before);
+      if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
+        if(before->right()==node_impl_pointer(0)){
+          inf.side=to_right;
+          inf.pos=before->impl();
+          return true;
+        }
+        else{
+          inf.side=to_left;
+          inf.pos=position->impl();
+          return true;
+        }
+      }
+      else return link_point(k,inf,ordered_unique_tag());
+    }
+  }
+
+  bool hinted_link_point(
+    key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag)
+  {
+    if(position->impl()==header()->left()){
+      if(size()>0&&!comp_(key(position->value()),k)){
+        inf.side=to_left;
+        inf.pos=position->impl();
+        return true;
+      }
+      else return lower_link_point(k,inf,ordered_non_unique_tag());
+    }
+    else if(position==header()){
+      if(!comp_(k,key(rightmost()->value()))){
+        inf.side=to_right;
+        inf.pos=rightmost()->impl();
+        return true;
+      }
+      else return link_point(k,inf,ordered_non_unique_tag());
+    }
+    else{
+      node_type* before=position;
+      node_type::decrement(before);
+      if(!comp_(k,key(before->value()))){
+        if(!comp_(key(position->value()),k)){
+          if(before->right()==node_impl_pointer(0)){
+            inf.side=to_right;
+            inf.pos=before->impl();
+            return true;
+          }
+          else{
+            inf.side=to_left;
+            inf.pos=position->impl();
+            return true;
+          }
+        }
+        else return lower_link_point(k,inf,ordered_non_unique_tag());
+      }
+      else return link_point(k,inf,ordered_non_unique_tag());
+    }
+  }
+
+  void delete_all_nodes(node_type* x)
+  {
+    if(!x)return;
+
+    delete_all_nodes(node_type::from_impl(x->left()));
+    delete_all_nodes(node_type::from_impl(x->right()));
+    this->final_delete_node_(static_cast<final_node_type*>(x));
+  }
+
+  bool in_place(value_param_type v,node_type* x,ordered_unique_tag)
+  {
+    node_type* y;
+    if(x!=leftmost()){
+      y=x;
+      node_type::decrement(y);
+      if(!comp_(key(y->value()),key(v)))return false;
+    }
+
+    y=x;
+    node_type::increment(y);
+    return y==header()||comp_(key(v),key(y->value()));
+  }
+
+  bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag)
+  {
+    node_type* y;
+    if(x!=leftmost()){
+      y=x;
+      node_type::decrement(y);
+      if(comp_(key(v),key(y->value())))return false;
+    }
+
+    y=x;
+    node_type::increment(y);
+    return y==header()||!comp_(key(y->value()),key(v));
+  }
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+  void detach_iterators(node_type* x)
+  {
+    iterator it=make_iterator(x);
+    safe_mode::detach_equivalent_iterators(it);
+  }
+#endif
+
+  template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
+  std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
+  {
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    std::pair<final_node_type*,bool>p=
+      this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
+    return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+  }
+
+  template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
+  iterator emplace_hint_impl(
+    iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
+  {
+    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+    BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+    std::pair<final_node_type*,bool>p=
+      this->final_emplace_hint_(
+        static_cast<final_node_type*>(position.get_node()),
+        BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
+    return make_iterator(p.first);
+  }
+
+  template<typename LowerBounder,typename UpperBounder>
+  std::pair<iterator,iterator>
+  range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
+  {
+    node_type* y=header();
+    node_type* z=root();
+
+    while(z){
+      if(!lower(key(z->value()))){
+        z=node_type::from_impl(z->right());
+      }
+      else if(!upper(key(z->value()))){
+        y=z;
+        z=node_type::from_impl(z->left());
+      }
+      else{
+        return std::pair<iterator,iterator>(
+          make_iterator(
+            lower_range(node_type::from_impl(z->left()),z,lower)),
+          make_iterator(
+            upper_range(node_type::from_impl(z->right()),y,upper)));
+      }
+    }
+
+    return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
+  }
+
+  template<typename LowerBounder,typename UpperBounder>
+  std::pair<iterator,iterator>
+  range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
+  {
+    return std::pair<iterator,iterator>(
+      begin(),
+      make_iterator(upper_range(root(),header(),upper)));
+  }
+
+  template<typename LowerBounder,typename UpperBounder>
+  std::pair<iterator,iterator>
+  range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
+  {
+    return std::pair<iterator,iterator>(
+      make_iterator(lower_range(root(),header(),lower)),
+      end());
+  }
+
+  template<typename LowerBounder,typename UpperBounder>
+  std::pair<iterator,iterator>
+  range(LowerBounder,UpperBounder,both_unbounded_tag)const
+  {
+    return std::pair<iterator,iterator>(begin(),end());
+  }
+
+  template<typename LowerBounder>
+  node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const
+  {
+    while(top){
+      if(lower(key(top->value()))){
+        y=top;
+        top=node_type::from_impl(top->left());
+      }
+      else top=node_type::from_impl(top->right());
+    }
+
+    return y;
+  }
+
+  template<typename UpperBounder>
+  node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const
+  {
+    while(top){
+      if(!upper(key(top->value()))){
+        y=top;
+        top=node_type::from_impl(top->left());
+      }
+      else top=node_type::from_impl(top->right());
+    }
+
+    return y;
+  }
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+  template<typename Archive>
+  void save_(
+    Archive& ar,const unsigned int version,const index_saver_type& sm,
+    ordered_unique_tag)const
+  {
+    super::save_(ar,version,sm);
+  }
+
+  template<typename Archive>
+  void load_(
+    Archive& ar,const unsigned int version,const index_loader_type& lm,
+    ordered_unique_tag)
+  {
+    super::load_(ar,version,lm);
+  }
+
+  template<typename Archive>
+  void save_(
+    Archive& ar,const unsigned int version,const index_saver_type& sm,
+    ordered_non_unique_tag)const
+  {
+    typedef duplicates_iterator<node_type,value_compare> dup_iterator;
+
+    sm.save(
+      dup_iterator(begin().get_node(),end().get_node(),value_comp()),
+      dup_iterator(end().get_node(),value_comp()),
+      ar,version);
+    super::save_(ar,version,sm);
+  }
+
+  template<typename Archive>
+  void load_(
+    Archive& ar,const unsigned int version,const index_loader_type& lm,
+    ordered_non_unique_tag)
+  {
+    lm.load(
+      ::boost::bind(&ordered_index::rearranger,this,_1,_2),
+      ar,version);
+    super::load_(ar,version,lm);
+  }
+
+  void rearranger(node_type* position,node_type *x)
+  {
+    if(!position||comp_(key(position->value()),key(x->value()))){
+      position=lower_bound(key(x->value())).get_node();
+    }
+    else if(comp_(key(x->value()),key(position->value()))){
+      /* inconsistent rearrangement */
+      throw_exception(
+        archive::archive_exception(
+          archive::archive_exception::other_exception));
+    }
+    else node_type::increment(position);
+
+    if(position!=x){
+      node_impl_type::rebalance_for_erase(
+        x->impl(),header()->parent(),header()->left(),header()->right());
+      node_impl_type::restore(
+        x->impl(),position->impl(),header()->impl());
+    }
+  }
+#endif /* serialization */
+
+  key_from_value key;
+  key_compare    comp_;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
+    BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+#pragma parse_mfunc_templ reset
+#endif
+};
+
+/* comparison */
+
+template<
+  typename KeyFromValue1,typename Compare1,
+  typename SuperMeta1,typename TagList1,typename Category1,
+  typename KeyFromValue2,typename Compare2,
+  typename SuperMeta2,typename TagList2,typename Category2
+>
+bool operator==(
+  const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
+  const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
+{
+  return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
+}
+
+template<
+  typename KeyFromValue1,typename Compare1,
+  typename SuperMeta1,typename TagList1,typename Category1,
+  typename KeyFromValue2,typename Compare2,
+  typename SuperMeta2,typename TagList2,typename Category2
+>
+bool operator<(
+  const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
+  const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
+{
+  return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
+}
+
+template<
+  typename KeyFromValue1,typename Compare1,
+  typename SuperMeta1,typename TagList1,typename Category1,
+  typename KeyFromValue2,typename Compare2,
+  typename SuperMeta2,typename TagList2,typename Category2
+>
+bool operator!=(
+  const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
+  const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
+{
+  return !(x==y);
+}
+
+template<
+  typename KeyFromValue1,typename Compare1,
+  typename SuperMeta1,typename TagList1,typename Category1,
+  typename KeyFromValue2,typename Compare2,
+  typename SuperMeta2,typename TagList2,typename Category2
+>
+bool operator>(
+  const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
+  const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
+{
+  return y<x;
+}
+
+template<
+  typename KeyFromValue1,typename Compare1,
+  typename SuperMeta1,typename TagList1,typename Category1,
+  typename KeyFromValue2,typename Compare2,
+  typename SuperMeta2,typename TagList2,typename Category2
+>
+bool operator>=(
+  const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
+  const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
+{
+  return !(x<y);
+}
+
+template<
+  typename KeyFromValue1,typename Compare1,
+  typename SuperMeta1,typename TagList1,typename Category1,
+  typename KeyFromValue2,typename Compare2,
+  typename SuperMeta2,typename TagList2,typename Category2
+>
+bool operator<=(
+  const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
+  const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
+{
+  return !(x>y);
+}
+
+/*  specialized algorithms */
+
+template<
+  typename KeyFromValue,typename Compare,
+  typename SuperMeta,typename TagList,typename Category
+>
+void swap(
+  ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
+  ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& y)
+{
+  x.swap(y);
+}
+
+} /* namespace multi_index::detail */
+
+/* ordered_index specifiers */
+
+template<typename Arg1,typename Arg2,typename Arg3>
+struct ordered_unique
+{
+  typedef typename detail::ordered_index_args<
+    Arg1,Arg2,Arg3>                                index_args;
+  typedef typename index_args::tag_list_type::type tag_list_type;
+  typedef typename index_args::key_from_value_type key_from_value_type;
+  typedef typename index_args::compare_type        compare_type;
+
+  template<typename Super>
+  struct node_class
+  {
+    typedef detail::ordered_index_node<Super> type;
+  };
+
+  template<typename SuperMeta>
+  struct index_class
+  {
+    typedef detail::ordered_index<
+      key_from_value_type,compare_type,
+      SuperMeta,tag_list_type,detail::ordered_unique_tag> type;
+  };
+};
+
+template<typename Arg1,typename Arg2,typename Arg3>
+struct ordered_non_unique
+{
+  typedef detail::ordered_index_args<
+    Arg1,Arg2,Arg3>                                index_args;
+  typedef typename index_args::tag_list_type::type tag_list_type;
+  typedef typename index_args::key_from_value_type key_from_value_type;
+  typedef typename index_args::compare_type        compare_type;
+
+  template<typename Super>
+  struct node_class
+  {
+    typedef detail::ordered_index_node<Super> type;
+  };
+
+  template<typename SuperMeta>
+  struct index_class
+  {
+    typedef detail::ordered_index<
+      key_from_value_type,compare_type,
+      SuperMeta,tag_list_type,detail::ordered_non_unique_tag> type;
+  };
+};
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+/* Boost.Foreach compatibility */
+
+template<
+  typename KeyFromValue,typename Compare,
+  typename SuperMeta,typename TagList,typename Category
+>
+inline boost::mpl::true_* boost_foreach_is_noncopyable(
+  boost::multi_index::detail::ordered_index<
+    KeyFromValue,Compare,SuperMeta,TagList,Category>*&,
+  boost::foreach::tag)
+{
+  return 0;
+}
+
+#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
+#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
+
+#endif
Index: /issm/trunk-jpl/externalpackages/boost/install-1.55-linux-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/boost/install-1.55-linux-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/boost/install-1.55-linux-static.sh	(revision 24593)
@@ -0,0 +1,54 @@
+#!/bin/bash
+#set -eu # Do not `run set -eu` because it causes some targets to fail
+
+
+# NOTE:
+# - Stop after bootstrap step and run `bjam --debug-configuration` to figure
+#	out which paths Boost is using to include Python. Make sure that each of
+#	the listed paths is covered by Python. If not, you must create a symbolic
+#	link from $ISSM_DIR/externalpackages/python to the location of the file
+#	that Boost is expecting. There is no way to get the Boost to compile with
+#	Python otherwise.
+#
+
+## Constants
+#
+VER="1_55_0"
+
+## Evnrionment
+#
+export CXXFLAGS='-std=c++98' # Setting CXXFLAGS to deal with C++11 incompatibility with Matlab's Boost
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/boost_${VER}.tar.gz" "boost_${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf boost_${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install src
+
+# Move source into 'src' directory
+mv boost_${VER}/* src/
+rm -rf boost_${VER}
+
+# Copy customized source and configuration files to 'src' driectory
+cp configs/1.55/linux/boost/multi_index/ordered_index.hpp src/boost/multi_index
+
+# Configure
+cd src
+./bootstrap.sh \
+	--prefix="${ISSM_DIR}/externalpackages/boost/install" \
+	--with-python=python2.7 \
+	--with-python-root="${ISSM_DIR}/externalpackages/python/install"
+
+# Modify project config to enable MPI
+printf "\n# Enable MPI\nusing mpi ;\n" >> project-config.jam
+
+# Compile and install
+./bjam link=static install
+
+# Copy binary to install directory
+mkdir ../install/bin
+cp bjam ../install/bin
Index: /issm/trunk-jpl/externalpackages/boost/install-1.55-linux.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/boost/install-1.55-linux.sh	(revision 24592)
+++ /issm/trunk-jpl/externalpackages/boost/install-1.55-linux.sh	(revision 24593)
@@ -1,40 +1,54 @@
 #!/bin/bash
-#set -eu
-#unhook set -eu because some target do fail and it is not a big deal
+#set -eu # Do not `run set -eu` because it causes some targets to fail
 
-#Note of caution:  stop after boostrap phase, and run 
-#bjam --debug-configuration, to figure out which paths boost is using to include 
-#python. make sure everyone of these paths is covered by python. If not, just make 
-#symlinks in externalpackages/python to what boost is expecting. Ther is NO WAY 
-#to get the boost library to include python support without doing that. 
 
-#Some cleanup
-rm -rf install boost_1_55_0 src
+# NOTE:
+# - Stop after bootstrap step and run `bjam --debug-configuration` to figure
+#	out which paths Boost is using to include Python. Make sure that each of
+#	the listed paths is covered by Python. If not, you must create a symbolic
+#	link from $ISSM_DIR/externalpackages/python to the location of the file
+#	that Boost is expecting. There is no way to get the Boost to compile with
+#	Python otherwise.
+#
+
+## Constants
+#
+VER="1_55_0"
+
+## Evnrionment
+#
+export CXXFLAGS='-std=c++98' # Setting CXXFLAGS to deal with C++11 incompatibility with Matlab's Boost
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/boost_${VER}.tar.gz" "boost_${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf boost_${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
 mkdir install src
 
-#Download from ISSM server
-$ISSM_DIR/scripts/DownloadExternalPackage.sh 'https://issm.ess.uci.edu/files/externalpackages/boost_1_55_0.tar.gz' 'boost_1_55_0.tar.gz'
+# Move source into 'src' directory
+mv boost_${VER}/* src/
+rm -rf boost_${VER}
 
-#Untar 
-tar -zxvf  boost_1_55_0.tar.gz
+# Copy customized source and configuration files to 'src' driectory
+cp configs/1.55/linux/boost/multi_index/ordered_index.hpp src/boost/multi_index
 
-#Move boost into install directory
-mv boost_1_55_0/* src
-rm -rf boost_1_55_0
+# Configure
+cd src
+./bootstrap.sh \
+	--prefix="${ISSM_DIR}/externalpackages/boost/install" \
+	--with-python=python2.7 \
+	--with-python-root="${ISSM_DIR}/externalpackages/python/install"
 
-#Setting CXXFLAGS to deal with C++11 incompatibility with Matlab's Boost
-export CXXFLAGS='-std=c++98'
+# Modify project config to enable MPI
+printf "\n# Enable MPI\nusing mpi ;\n" >> project-config.jam
 
-#Configure and compile
-cd src 
-./bootstrap.sh \
-	--prefix="$ISSM_DIR/externalpackages/boost/install" \
-	--with-python=python2.7 \
-	--with-python-root="$ISSM_DIR/externalpackages/python/install" 
-
-#Compile boost
+# Compile and install
 ./bjam install
 
-#put bjam into install also: 
+# Copy binary to install directory
 mkdir ../install/bin
 cp bjam ../install/bin
Index: /issm/trunk-jpl/externalpackages/boost/install-1.72-linux-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/boost/install-1.72-linux-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/boost/install-1.72-linux-static.sh	(revision 24593)
@@ -0,0 +1,48 @@
+#!/bin/bash
+#set -eu # Do not `run set -eu` because it causes some targets to fail
+
+
+# NOTE:
+# - Stop after bootstrap step and run `b2 --debug-configuration` to figure
+#	out which paths Boost is using to include Python. Make sure that each of
+#	the listed paths is covered by Python. If not, you must create a symbolic
+#	link from $ISSM_DIR/externalpackages/python to the location of the file
+#	that Boost is expecting. There is no way to get the Boost to compile with
+#	Python otherwise.
+#
+
+## Constants
+#
+VER="1_72_0"
+
+## Envrionment
+#
+#export CXXFLAGS='-std=c++98' # Setting CXXFLAGS to deal with C++11 incompatibility with Matlab's Boost
+#export CXXFLAGS='-std=c++11'
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/boost_${VER}.tar.gz" "boost_${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf boost_${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install src
+
+# Move source into 'src' directory
+mv boost_${VER}/* src/
+rm -rf boost_${VER}
+
+# Configure
+cd src
+./bootstrap.sh \
+	--prefix="${ISSM_DIR}/externalpackages/boost/install" \
+	--with-python=python2.7 \
+	--with-python-root="${ISSM_DIR}/externalpackages/python/install"
+
+# Modify project config to enable MPI
+printf "\n# Enable MPI\nusing mpi ;\n" >> project-config.jam
+
+# Compile and install
+./b2 link=static install
Index: /issm/trunk-jpl/externalpackages/boost/install-1.72-linux.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/boost/install-1.72-linux.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/boost/install-1.72-linux.sh	(revision 24593)
@@ -0,0 +1,48 @@
+#!/bin/bash
+#set -eu # Do not `run set -eu` because it causes some targets to fail
+
+
+# NOTE:
+# - Stop after bootstrap step and run `b2 --debug-configuration` to figure
+#	out which paths Boost is using to include Python. Make sure that each of
+#	the listed paths is covered by Python. If not, you must create a symbolic
+#	link from $ISSM_DIR/externalpackages/python to the location of the file
+#	that Boost is expecting. There is no way to get the Boost to compile with
+#	Python otherwise.
+#
+
+## Constants
+#
+VER="1_72_0"
+
+## Envrionment
+#
+#export CXXFLAGS='-std=c++98' # Setting CXXFLAGS to deal with C++11 incompatibility with Matlab's Boost
+#export CXXFLAGS='-std=c++11'
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/boost_${VER}.tar.gz" "boost_${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf boost_${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install src
+
+# Move source into 'src' directory
+mv boost_${VER}/* src/
+rm -rf boost_${VER}
+
+# Configure
+cd src
+./bootstrap.sh \
+	--prefix="${ISSM_DIR}/externalpackages/boost/install" \
+	--with-python=python2.7 \
+	--with-python-root="${ISSM_DIR}/externalpackages/python/install"
+
+# Modify project config to enable MPI
+printf "\n# Enable MPI\nusing mpi ;\n" >> project-config.jam
+
+# Compile and install
+./b2 --toolset=gcc install
Index: /issm/trunk-jpl/externalpackages/cmake/install.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/cmake/install.sh	(revision 24592)
+++ /issm/trunk-jpl/externalpackages/cmake/install.sh	(revision 24593)
@@ -1,25 +1,33 @@
 #!/bin/bash
-set -eu 
+set -eu
+
+
+## Constants
+#
 VER="3.16.2"
 
-#Some cleanup
-rm -rf install cmake-$VER
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/cmake-${VER}.tar.gz" "cmake-${VER}.tar.gz"
 
-#Download from ISSM server
-$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/cmake-$VER.tar.gz" "cmake-$VER.tar.gz"
+# Unpack source
+tar -zxvf cmake-${VER}.tar.gz
 
-#Untar 
-tar -zxvf  cmake-$VER.tar.gz
+# Cleanup
+rm -rf install
 
-#Move cmake into install directory
-mv cmake-$VER install
+# Move source into 'install' directory
+mv cmake-${VER} install
 
-#Compile cmake
-cd install 
-#./bootstrap --prefix=$ISSM_DIR/externalpackages/cmake/install #(Breaks on ronne)
-./configure --prefix=$ISSM_DIR/externalpackages/cmake/install
+# Configure
+cd install
+#./bootstrap \
+#	--prefix=${ISSM_DIR}/externalpackages/cmake/install # Breaks on ronne
+./configure \
+	--prefix=${ISSM_DIR}/externalpackages/cmake/install
+
+# Compile
 if [ $# -eq 0 ]; then
 	make
-else 
-	make -j$1; 
+else
+	make -j $1;
 fi
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/cmake/BuildDakotaCustom.cmake
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/cmake/BuildDakotaCustom.cmake	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/cmake/BuildDakotaCustom.cmake	(revision 24593)
@@ -0,0 +1,95 @@
+##############################################################################
+#
+# Template CMake Configuration File.
+#
+##############################################################################
+# The following CMake variables represent the minimum set of variables
+# that are required to allow Dakota to
+#   * find all prerequisite third party libraries (TPLs)
+#   * configure compiler and MPI options
+#   * set Dakota install path
+#
+# Instructions:
+# 1. Read Dakota/INSTALL - Source Quick Start to use this template file.
+#
+# 2. Uncomment CMake variables below ONLY for values you need to change for
+#    your platform. Edit variables as needed.
+#
+#    For example, if you are using a custom install of Boost, installed in
+#    /home/me/usr/boost, uncomment both CMake Boost variables  and edit
+#    paths:
+#       set(BOOST_ROOT
+#           "/home/me/usr/boost"
+#           CACHE PATH "Use non-standard Boost install" FORCE)
+#       set( Boost_NO_SYSTEM_PATHS TRUE
+#            CACHE BOOL "Supress search paths other than BOOST_ROOT" FORCE)
+#
+#    Save file and exit.
+#
+# 6. Run CMake with script file. At terminal window, type:
+#      $ cmake -C BuildCustom.cmake $DAK_SRC
+#
+#    If you have not followed instructions in INSTALL -Source Quick Start,
+#    you will need to replace BuildCustom.cmake with the actual filename of
+#    this file and $DAK_SRC with the actual path to Dakota source.
+#
+##############################################################################
+
+##############################################################################
+# Set BLAS, LAPACK library paths ONLY if in non-standard locations
+##############################################################################
+set( BLAS_LIBS
+      "$ENV{BLAS_LIBS}"
+      CACHE FILEPATH "Use non-standard BLAS library path" FORCE )
+set( LAPACK_LIBS
+      "$ENV{LAPACK_LIBS}"
+      CACHE FILEPATH "Use non-standard BLAS library path" FORCE )
+
+##############################################################################
+# Set additional compiler options
+# Uncomment and replace <flag> with actual compiler flag, e.g. -xxe4.2
+##############################################################################
+set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS}"
+     CACHE STRING "C Flags my platform" )
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}"
+     CACHE STRING "CXX Flags for my platform" )
+set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}"
+     CACHE STRING "Fortran Flags for my platform" )
+
+##############################################################################
+# Set MPI options
+# Recommended practice is to set DAKOTA_HAVE_MPI and set MPI_CXX_COMPILER
+# to a compiler wrapper.
+##############################################################################
+set( DAKOTA_HAVE_MPI ON
+     CACHE BOOL "Build with MPI enabled" FORCE)
+set( MPI_INCLUDE_PATH "$ENV{MPI_INSTALL}/include"
+     CACHE FILEPATH "Use MPI headers" FORCE)
+set( MPI_LIBRARY "-L$ENV{MPI_INSTALL}/lib -lmpich"
+     CACHE FILEPATH "Use MPI library" FORCE)
+
+##############################################################################
+# Set Boost path if CMake cannot find your installed version of Boost or
+# if you have a custom Boost install location.
+##############################################################################
+set(BOOST_ROOT
+    $ENV{BOOST_ROOT}
+    CACHE PATH "Use non-standard Boost install" FORCE)
+set( Boost_NO_SYSTEM_PATHS TRUE
+     CACHE BOOL "Supress search paths other than BOOST_ROOT" FORCE)
+
+##############################################################################
+# Set Trilinos path if you want have a custom Trilinos install location. If
+# not set, the Trilinos package, teuchos, will be build during the Dakota
+# build.
+##############################################################################
+#set( Trilinos_DIR
+#      "path/to/Trilinos/install"
+#      CACHE PATH "Path to installed Trilinos" FORCE )
+
+##############################################################################
+# Customize DAKOTA
+##############################################################################
+set( CMAKE_INSTALL_PREFIX
+     $ENV{DAK_INSTALL}
+     CACHE PATH "Path to Dakota installation" )
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/cmake/DakotaDev.cmake
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/cmake/DakotaDev.cmake	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/cmake/DakotaDev.cmake	(revision 24593)
@@ -0,0 +1,18 @@
+# CMake options for DAKOTA developer builds
+
+# Developer options
+#set(DAKOTA_HAVE_MPI TRUE CACHE BOOL "Enable MPI in DAKOTA?")
+set(ENABLE_DAKOTA_DOCS FALSE CACHE BOOL "Enable DAKOTA documentation build")
+set(ENABLE_SPEC_MAINT FALSE CACHE BOOL
+  "Enable DAKOTA specification maintenance mode?")
+set(PECOS_ENABLE_TESTS FALSE CACHE BOOL "Enable Pecos-specific tests?")
+
+# Not included from Mike's configs, but may help some
+
+# Disable optional X graphics
+#-DHAVE_X_GRAPHICS:BOOL=FALSE
+set(HAVE_X_GRAPHICS OFF CACHE BOOL "Disable dependency on X libraries" FORCE)
+
+# CMake 2.8.6 has problems with RHEL6/Boost -- the following is a workaround
+#-DBoost_NO_BOOST_CMAKE=ON
+#set(Boost_NO_BOOST_CMAKE ON CACHE BOOL "Obtain desired behavior on RHEL6" FORCE)
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/DDACE/src/Analyzer/MainEffectsExcelOutput.cpp
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/DDACE/src/Analyzer/MainEffectsExcelOutput.cpp	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/DDACE/src/Analyzer/MainEffectsExcelOutput.cpp	(revision 24593)
@@ -0,0 +1,284 @@
+#include "MainEffectsExcelOutput.h"
+
+    std::ostringstream ss;
+
+    MainEffectsExcelOutput::MainEffectsExcelOutput(){;}
+
+    MainEffectsExcelOutput::~MainEffectsExcelOutput(){;}
+
+    std::string MainEffectsExcelOutput::outputColumnHeaders
+                    (int numInputs, int numOutputs) {
+
+        std::ostringstream ss;
+
+         /* input variables */
+         for (int i=0; i<numInputs; i++) {
+         	if (ss.str()!="") ss << ",";
+         	ss << "in(" << i << ")";
+         }
+
+         /* output variables */
+         for (int i=0; i<numOutputs; i++) {
+         	if (ss.str()!="") ss << ",";
+         	ss << "out(" << i << ")";
+         }
+
+         /* number of observations */
+         ss << ",nObservations";
+
+         /* sum of all observations */
+         ss << ",sumOfAllObservations";
+
+         /* average of all observations */
+         ss << ",avgOfAllObservation";
+
+         /* sum of squares of all observations */
+         ss << ",sumOfSquaresOfAllObservations";
+
+         /* degrees of freedom of all observations */
+         ss << ",degreesOfFreedomOfAllObservations";
+
+         /* variance of all Observations */
+         ss << ",varianceOfAllObservations";
+
+         /* sum */
+         ss << ",sum";
+
+         /* average */
+         ss << ",average";
+
+         /* sum of squares */
+         ss << ",sumOfSquares";
+
+         /* variance */
+         ss << ",variance";
+
+         /* sum of squares between groups */
+         ss << ",sumOfSquaresBetweenGroups";
+
+         /* degrees of freedom between groups */
+         ss << ",degreesOfFreedomBetweenGroups";
+
+         /* variance between groups */
+         ss << ",varianceBetweenGroups";
+
+         /* sum of squares between groups */
+         ss << ",sumOfSquaresWithinGroups";
+
+         /* degrees of freedom between groups */
+         ss << ",degreesOfFreedomWithinGroups";
+
+         /* variance between groups */
+         ss << ",varianceWithinGroups";
+
+         /* F */
+         ss << ",F";
+
+         ss << "\n";
+
+         return(ss.str());
+    }
+
+
+    std::string MainEffectsExcelOutput::outputMainEffects
+         (int inputVarIndex, int numInputs,
+          int outputVarIndex, int numOutputs,
+          DDaceMainEffects::Factor factor) {
+
+        std::ostringstream ss;
+        int numberOfLevels =
+            factor.getNumberOfLevels();
+
+        for (int i=0; i<numberOfLevels; i++) {
+        	ss << outputMainEffects (inputVarIndex, numInputs,
+                   outputVarIndex, numOutputs, factor, i);
+        }
+
+        return(ss.str());
+     }
+
+    std::string MainEffectsExcelOutput::outputMainEffects
+         (int inputVarIndex, int numInputs,
+          int outputVarIndex, int numOutputs,
+          DDaceMainEffects::Factor factor,
+          int indexOfInputValue) {
+
+        std::ostringstream ss;
+
+         /* put an F under the input variable */
+         for (int i=0; i<numInputs; i++) {
+         	if (ss.str()!="") ss << ",";
+         	if (i==inputVarIndex) ss << "F";
+         }
+
+         /* put an R under the output variable */
+         for (int i=0; i<numOutputs; i++) {
+         	if (ss.str()!="") ss << ",";
+         	if (i==outputVarIndex) ss << "R";
+         }
+
+         /* number of observations */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.getNumberOfObservations();
+         }
+
+
+         /* sum of all observations */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             DDaceMainEffects::Response response = factor.getResponse();
+             std::vector<double> responses = response.responses_;
+             ss << response.getSumPop();
+         }
+
+         /* average of all Observation */
+         ss << ",";
+         if (indexOfInputValue==0) {
+          	 DDaceMainEffects::Response response = factor.getResponse();
+             ss << response.getAveragePop();
+         }
+
+         /* sum of squares for Observation */
+         ss << ",";
+         if (indexOfInputValue==0) {
+          	 DDaceMainEffects::Response response = factor.getResponse();
+             ss << response.getSumOfSquaresPop();
+         }
+
+         /* degrees of freedom for all Observation*/
+         ss << ",";
+         if (indexOfInputValue==0) {
+             int dTotal = factor.getNumberOfObservations() - 1;
+             ss << dTotal;
+         }
+
+         /* variance for all Observations */
+         ss << ",";
+         if (indexOfInputValue==0) {
+         	DDaceMainEffects::Response response = factor.getResponse();
+             ss << response.getVariancePop();
+         }
+
+         /* sum */
+         ss << "," << factor.getLevelSum(indexOfInputValue);
+
+         /* average */
+         ss << "," << factor.getLevelAverage(indexOfInputValue);
+
+         /* sum of squares */
+         ss << "," << factor.getLevelSumOfSquares(indexOfInputValue);
+
+         /* variance */
+         ss << "," << factor.getLevelVariance(indexOfInputValue);
+
+         /* sum of squares between groups */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.sumOfSquaresBetweenGroups();
+         }
+
+         /* degrees of freedom between groups */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.doFBetween();
+         }
+
+         /* variance between groups */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.varianceBetweenGroups();
+         }
+
+         /* sum of squares within groups */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.sumOfSquaresWithinGroups();
+         }
+
+         /* degrees of freedom within groups */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.doFWithin();
+         }
+
+         /* variance within groups */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.varianceWithinGroups();
+         }
+
+         /* F */
+         ss << ",";
+         if (indexOfInputValue==0) {
+             ss << factor.Fdata();
+         }
+
+
+         ss << "\n";
+
+         return(ss.str());
+     }
+
+    std::string MainEffectsExcelOutput::computeExcelOutput
+        (std::vector<std::vector<double> > vectorInputData,
+         std::vector<std::vector<double> > vectorOutputData){
+
+        std::ostringstream ss;
+
+    	/* error check */
+    	if (vectorInputData.size() == 0) return("");
+    	if (vectorOutputData.size() == 0) return("");
+
+
+    	MainEffectsConverter converter;
+
+         /* Replace every INPUT data value with a counting number */
+         VectorCountingNumbersAndCount vectorCountingNumbersAndCount =
+             converter.convertAllDoublesToCountingNumbers(vectorInputData);
+         std::vector<std::vector<int> > vectorInputIndicies =
+                vectorCountingNumbersAndCount.vectorCountingNumbers;
+         int numberOfCountingNumbers = vectorCountingNumbersAndCount.count;
+
+        /* How many columns are in the input table? */
+        int numInputs = vectorInputData[0].size();
+
+        /* How many columns are in the output table? */
+        int numOutputs = vectorOutputData[0].size();
+
+        /* output the column headers */
+        ss << outputColumnHeaders (numInputs, numOutputs);
+
+        /* pair input column 1 with output column 1 */
+        /* pair input column 1 with output column 2 */
+        /* pair input column 1 with output column 3 */
+        /* etc.                                     */
+        /* pair input column 2 with output column 1 */
+        /* pair input column 2 with output column 2 */
+        /* pair input column 2 with output column 3 */
+        /* etc.                                     */
+        for (int indexInput=0; indexInput<numInputs; indexInput++) {
+        for (int indexOutput=0; indexOutput<numOutputs; indexOutput++) {
+
+             /* slice out the selected input var & selected output var */
+             DDaceMainEffects::Factor factor =
+                 converter.sliceOutOneInputVarAndOneOutputVar
+                      (vectorInputIndicies,    //data from all input vars
+                       vectorOutputData, //data from all output vars
+                       indexInput,             //slice out this input var
+                       indexOutput,            //slice out this output var
+                       numberOfCountingNumbers);  //# of different input values
+
+
+
+             ss << outputMainEffects (indexInput, numInputs, indexOutput,
+                    numOutputs, factor);
+	     std::cout << ss.str() << std::endl;
+
+
+        }//for indexOutput
+        }//for indexInput
+
+
+    	return(ss.str());
+    }
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/pecos/src/pecos_global_defs.hpp
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/pecos/src/pecos_global_defs.hpp	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/pecos/src/pecos_global_defs.hpp	(revision 24593)
@@ -0,0 +1,190 @@
+/*  _______________________________________________________________________
+
+    PECOS: Parallel Environment for Creation Of Stochastics
+    Copyright (c) 2011, Sandia National Laboratories.
+    This software is distributed under the GNU Lesser General Public License.
+    For more information, see the README file in the top Pecos directory.
+    _______________________________________________________________________ */
+
+#ifndef PECOS_GLOBAL_DEFS_H
+#define PECOS_GLOBAL_DEFS_H
+
+#include <iostream>
+#include <cfloat>  // for DBL_MIN, DBL_MAX
+#include <cmath>
+#include <cstdlib>
+
+#include <boost/math/constants/constants.hpp>
+
+namespace Pecos {
+
+// --------------
+// Special values
+// --------------
+/// the value for PI used in various numerical routines
+#ifndef PI
+const double PI = boost::math::constants::pi<double>();
+#endif
+
+/// special value returned by index() when entry not found
+const size_t _NPOS = ~(size_t)0; // one's complement
+
+/// used in ostream data output functions
+const int WRITE_PRECISION = 10;
+
+/// small value used for protecting division by zero, etc.; an alternative
+/// to DBL_MIN that is less likely to cause underflow/overflow when numbers
+/// larger than it are used in calculations
+const double SMALL_NUMBER = 1.e-25;
+/// large value used as a surrogate for infinity in error traps; an alternative
+/// to DBL_MAX or inf that is less likely to cause underflow/overflow when used
+/// in subsequent calculations
+const double LARGE_NUMBER = 1.e+50;
+
+// define special values for vector/matrix data copying modes
+enum { DEFAULT_COPY=0, SHALLOW_COPY, DEEP_COPY };
+
+// define special values for ExpansionConfigOptions::outputLevel
+enum { SILENT_OUTPUT, QUIET_OUTPUT, NORMAL_OUTPUT, VERBOSE_OUTPUT,
+       DEBUG_OUTPUT };
+
+// define special values for ranVarTypesX/U
+enum { NO_TYPE=0, CONTINUOUS_DESIGN, STD_NORMAL, NORMAL, BOUNDED_NORMAL,
+       LOGNORMAL, BOUNDED_LOGNORMAL, STD_UNIFORM, UNIFORM, LOGUNIFORM,
+       TRIANGULAR, STD_EXPONENTIAL, EXPONENTIAL, STD_BETA, BETA, STD_GAMMA,
+       GAMMA, GUMBEL, FRECHET, WEIBULL, HISTOGRAM_BIN, CONTINUOUS_INTERVAL,
+       CONTINUOUS_STATE, STOCHASTIC_EXPANSION };
+
+// define special values for secondaryACVarMapTargets/secondaryADVarMapTargets
+enum { NO_TARGET=0, CDV_LWR_BND, CDV_UPR_BND, DDRIV_LWR_BND, DDRIV_UPR_BND,
+       N_MEAN, N_STD_DEV, N_LWR_BND, N_UPR_BND, N_LOCATION, N_SCALE, LN_MEAN,
+       LN_STD_DEV, LN_LAMBDA, LN_ZETA, LN_ERR_FACT, LN_LWR_BND, LN_UPR_BND,
+       U_LWR_BND, U_UPR_BND, U_LOCATION, U_SCALE, LU_LWR_BND, LU_UPR_BND,
+       T_MODE, T_LWR_BND, T_UPR_BND, T_LOCATION, T_SCALE, E_BETA,
+       BE_ALPHA, BE_BETA, BE_LWR_BND, BE_UPR_BND, GA_ALPHA, GA_BETA,
+       GU_ALPHA, GU_BETA, F_ALPHA, F_BETA, W_ALPHA, W_BETA,
+       P_LAMBDA, BI_P_PER_TRIAL, BI_TRIALS, NBI_P_PER_TRIAL, NBI_TRIALS,
+       GE_P_PER_TRIAL, HGE_TOT_POP, HGE_SEL_POP, HGE_FAILED,
+       CSV_LWR_BND, CSV_UPR_BND, DSRIV_LWR_BND, DSRIV_UPR_BND };
+
+/// derived basis approximation types
+enum { NO_BASIS=0, //FOURIER_BASIS, EIGEN_BASIS,
+       GLOBAL_NODAL_INTERPOLATION_POLYNOMIAL,
+       PIECEWISE_NODAL_INTERPOLATION_POLYNOMIAL,
+       GLOBAL_HIERARCHICAL_INTERPOLATION_POLYNOMIAL,
+       PIECEWISE_HIERARCHICAL_INTERPOLATION_POLYNOMIAL,
+       GLOBAL_REGRESSION_ORTHOGONAL_POLYNOMIAL,
+       GLOBAL_PROJECTION_ORTHOGONAL_POLYNOMIAL,
+       GLOBAL_ORTHOGONAL_POLYNOMIAL };
+       //PIECEWISE_REGRESSION_ORTHOGONAL_POLYNOMIAL,
+       //PIECEWISE_PROJECTION_ORTHOGONAL_POLYNOMIAL,
+       //PIECEWISE_ORTHOGONAL_POLYNOMIAL };
+
+/// derived basis polynomial types (orthogonal polynomial order follows
+/// uncertain variable spec order of normal, uniform, exponential, beta, gamma)
+enum { NO_POLY=0, HERMITE_ORTHOG, LEGENDRE_ORTHOG, LAGUERRE_ORTHOG,
+       JACOBI_ORTHOG, GEN_LAGUERRE_ORTHOG, CHEBYSHEV_ORTHOG, NUM_GEN_ORTHOG,
+       LAGRANGE_INTERP, HERMITE_INTERP, PIECEWISE_LINEAR_INTERP,
+       PIECEWISE_QUADRATIC_INTERP, PIECEWISE_CUBIC_INTERP };
+
+/// integration rules within VPISparseGrid (1-12: CC through User-closed)
+/// and beyond (GOLUB_WELSCH, NEWTON_COTES)
+enum { NO_RULE=0, CLENSHAW_CURTIS, FEJER2, GAUSS_PATTERSON, GAUSS_LEGENDRE,
+       GAUSS_HERMITE, GEN_GAUSS_HERMITE, GAUSS_LAGUERRE, GEN_GAUSS_LAGUERRE,
+       GAUSS_JACOBI, GENZ_KEISTER, /*USER_OPEN, USER_CLOSED,*/ GOLUB_WELSCH,
+       NEWTON_COTES };
+
+// growth rules within VPISparseGrid
+//enum { DEFAULT_GROWTH=0, SLOW_LINEAR, SLOW_LINEAR_ODD, MODERATE_LINEAR,
+//       SLOW_EXPONENTIAL, MODERATE_EXPONENTIAL, FULL_EXPONENTIAL };
+
+/// options for synchronizing linear and exponential growth rule settings
+/// (consistent with slow/moderate/full growth for new level_to_growth_*
+/// functions in sandia_rules.cpp)
+enum { SLOW_RESTRICTED_GROWTH, MODERATE_RESTRICTED_GROWTH,
+       UNRESTRICTED_GROWTH };
+
+/// solution approaches for calculating the polynomial basis coefficients
+/// (options for ExpansionConfigOptions::expCoeffsSolnApproach)
+enum { QUADRATURE, CUBATURE, LIGHTWEIGHT_SPARSE_GRID, COMBINED_SPARSE_GRID,
+       HIERARCHICAL_SPARSE_GRID, SAMPLING, DEFAULT_REGRESSION,
+       DEFAULT_LEAST_SQ_REGRESSION, SVD_LEAST_SQ_REGRESSION,
+       EQ_CON_LEAST_SQ_REGRESSION, BASIS_PURSUIT, BASIS_PURSUIT_DENOISING,
+       ORTHOG_MATCH_PURSUIT, LASSO_REGRESSION, LEAST_ANGLE_REGRESSION,
+       ORTHOG_LEAST_INTERPOLATION };
+/// options for BasisConfigOptions::nestingOverride (inactive)
+enum { NO_NESTING_OVERRIDE=0, NESTED, NON_NESTED };
+/// options for overriding the default growth restriction policy
+enum { NO_GROWTH_OVERRIDE=0, RESTRICTED, UNRESTRICTED };
+/// options for ExpansionConfigOptions::refinementType (inactive)
+enum { NO_REFINEMENT=0, P_REFINEMENT, H_REFINEMENT };
+/// options for ExpansionConfigOptions::refinementControl
+enum { NO_CONTROL=0, UNIFORM_CONTROL, LOCAL_ADAPTIVE_CONTROL,
+       DIMENSION_ADAPTIVE_CONTROL_SOBOL, DIMENSION_ADAPTIVE_CONTROL_DECAY,
+       DIMENSION_ADAPTIVE_CONTROL_GENERALIZED };
+
+/// options for expansion basis type
+enum { DEFAULT_BASIS=0, TENSOR_PRODUCT_BASIS, TOTAL_ORDER_BASIS,
+       ADAPTED_BASIS_GENERALIZED, ADAPTED_BASIS_EXPANDING_FRONT,
+       NODAL_INTERPOLANT, HIERARCHICAL_INTERPOLANT };
+
+/// mode of integration driver: integration versus interpolation
+enum { DEFAULT_MODE=0, INTEGRATION_MODE, INTERPOLATION_MODE };
+
+/// options for local basis functions within PiecewiseInterpPolynomial
+enum { LINEAR_EQUIDISTANT, LINEAR, QUADRATIC_EQUIDISTANT, QUADRATIC,
+       CUBIC_EQUIDISTANT, CUBIC };
+
+/// special values for nodal interpolation of variance and variance gradient
+enum { INTERPOLATION_OF_PRODUCTS, REINTERPOLATION_OF_PRODUCTS,
+       PRODUCT_OF_INTERPOLANTS_FAST, PRODUCT_OF_INTERPOLANTS_FULL };
+
+/// special values for polynomial expansion combination
+enum { NO_COMBINE=0,  ADD_COMBINE, MULT_COMBINE, ADD_MULT_COMBINE };
+
+
+// ----------------
+// Standard streams
+// ----------------
+#define PCout std::cout
+#define PCerr std::cerr
+
+
+// --------------
+// Global objects
+// --------------
+/// Dummy struct for overloading letter-envelope constructors.
+/** BaseConstructor is used to overload the constructor for the base class
+    portion of letter objects.  It avoids infinite recursion (Coplien p.139)
+    in the letter-envelope idiom by preventing the letter from instantiating
+    another envelope.  Putting this struct here avoids circular dependencies. */
+struct BaseConstructor {
+  BaseConstructor(int = 0) {} ///< C++ structs can have constructors
+};
+
+
+// ----------------
+// Global functions
+// ----------------
+
+/// global function which handles serial or parallel aborts
+void abort_handler(int code);
+
+
+inline void abort_handler(int code)
+{ std::exit(code); } // for now, prior to use of MPI
+
+
+/** Templatized abort_handler_t method that allows for convenient return from
+    methods that otherwise have no sensible return from error clauses.  Usage:
+    MyType& method() { return abort_handler<MyType&>(-1); } */
+template <typename T>
+T abort_handler_t(int code)
+{
+  abort_handler(code);
+  throw code;
+}
+
+} // namespace Pecos
+
+#endif // PECOS_GLOBAL_DEFS_H
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/surfpack/src/surfaces/nkm/NKM_KrigingModel.cpp
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/surfpack/src/surfaces/nkm/NKM_KrigingModel.cpp	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/packages/surfpack/src/surfaces/nkm/NKM_KrigingModel.cpp	(revision 24593)
@@ -0,0 +1,4681 @@
+#include "NKM_SurfPack.hpp"
+#include "NKM_KrigingModel.hpp"
+//#include "Accel.hpp"
+//#include "NKM_LinearRegressionModel.hpp"
+#include <math.h>
+#include <iostream>
+#include <cfloat>
+
+
+#ifdef SURFPACK_HAVE_BOOST_SERIALIZATION
+BOOST_CLASS_EXPORT(nkm::KrigingModel)
+#endif
+
+
+namespace nkm {
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::ostringstream;
+
+
+//#define __KRIG_ERR_CHECK__
+#define __NKM_UNBIASED_LIKE__
+
+
+
+// typical constructor
+KrigingModel::KrigingModel(const SurfData& sd, const ParamMap& params)
+  : SurfPackModel(sd,sd.getIOut()), numVarsr(sd.getNVarsr()),
+    numTheta(numVarsr), numPoints(sdBuild.getNPts()), XR(sdBuild.xr)
+{
+  //printf("calling the right KrigingModel constructor\n"); fflush(stdout);
+
+  //if the SurfDataScaler class does what it's supposed to (the only private content in sdBuild that a Model can access are the scaling bits and then only through SurfDataScaler, and only the model can see inside the scaler) the next line will cause an error when you try to compile with it uncommented, that is intentional
+  //printf("scaler->mySd.iout=%d\n",scaler.mySd.iout);
+
+  // OPTIONS PARSING
+  ParamMap::const_iterator param_it;
+
+  // *************************************************************
+  // control verbosity outputLevel
+  // *************************************************************
+  param_it = params.find("verbosity");
+  if (param_it != params.end() && param_it->second.size() > 0)
+    outputLevel=static_cast<short>(std::atoi(param_it->second.c_str()));
+  // outputLevel is a member of nkm::SurfPackModel which nkm::KrigingModel
+  // is derived from
+
+  // ********************************************************************
+  // does the user want to use derivative information to build the
+  // Kriging model (e.g. Gradient Enhanced Kriging)
+  // ********************************************************************
+
+  buildDerOrder=0; //default is regular Kriging (i.e. not GEK)
+  param_it = params.find("derivative_order");
+  if(param_it != params.end() && param_it->second.size() > 0)
+    buildDerOrder = std::atoi(param_it->second.c_str());
+  if(buildDerOrder==0) {//Kriging
+    numEqnAvail=numPoints;
+    nDer=1;
+    Der.newSize(numVarsr,nDer); Der.zero();
+  } else if(buildDerOrder==1) { //Gradient Enhanced Kriging (GEK)
+    numEqnAvail=(1+numVarsr)*numPoints;
+    multi_dim_poly_power(Der, numVarsr, 1);  //use all mixed partial
+    //derivatives, up to first order, of the basis functions
+    nDer=Der.getNCols(); //for GradKrigingModel nDer=(1+numVarsr);
+    //printf("nDer=%d\n",nDer);
+    int data_der_order=sdBuild.getDerOrder();
+    if(data_der_order<1) {
+      std::cerr << "the order of derivative information available in the "
+		<< "build data is " << data_der_order << "\n"
+		<< "You need to supply gradients of the output in order to "
+		<< "construct a\nGradient Enhanced Kriging (GEK) Model."
+		<< std::endl;
+      assert(false);
+    }
+  }
+  else{
+    std::cerr << "derivative_order=" << buildDerOrder
+	      << " in the nkm::KrigingModel constructor.\n"
+	      << "For Kriging you must use derivative_order=0.\n"
+	      << "For Gradient Enhanced Kriging (GEK) you must use "
+	      << "derivative_order=1.\nHigher order derivative "
+	      << "enhanced Kriging (e.g. Hessian Enhanced Kriging)\n"
+	      << "has not been implemented." << std::endl;
+    assert(false);
+  }
+
+  // *************************************************************
+  // detect an anchor point if present this is the one point that
+  // we make sure that the equationSelectingCholR does not discard
+  // *************************************************************
+  iAnchorPoint=0;
+  ifHaveAnchorPoint=false;
+  param_it = params.find("anchor_index");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    ifHaveAnchorPoint=true;
+    //printf("nkm::KrigingModel() sees an anchor point\n");
+    //fflush(stdout);
+    iAnchorPoint=std::atoi(param_it->second.c_str());
+    //printf("iAnchorPoint=%d\n",iAnchorPoint);
+    //fflush(stdout);
+    if(!((0<=iAnchorPoint)&&(iAnchorPoint<numPoints))) {
+      std::cerr << "You can't specify an anchor point that isn't one of "
+		<< "the build points" << std::endl;
+      assert(false);
+    }
+  }
+
+  // *************************************************************
+  // this starts the input section about scaling the data
+  // *************************************************************
+
+  MtxDbl min_max_xr(numVarsr, 2);
+  bool if_user_specified_lower_bounds=false;
+  param_it = params.find("lower_bounds");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    if_user_specified_lower_bounds=true;
+    if(min_max_xr.putCols(param_it->second,0)) {
+      std::cerr << "You didn't enter the right number of lower bounds"
+		<< std::endl;
+      assert(false);
+    }
+  }
+
+  bool if_user_specified_upper_bounds=false;
+  param_it = params.find("upper_bounds");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    if_user_specified_upper_bounds=true;
+    if(min_max_xr.putCols(param_it->second,1)) {
+      std::cerr << "You didn't enter the right number of upper bounds"
+		<< std::endl;
+      assert(false);
+    }
+  }
+
+  if(!(if_user_specified_lower_bounds==if_user_specified_upper_bounds)) {
+    std::cerr << "Your options are to\n(A) specify both the upper and lower, or\n(B) specify neither the upper nor lower,\nbounds of the domain of the Kriging Model\n";
+    assert(false);
+  }
+
+  if(if_user_specified_lower_bounds==true) {
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      if(!(min_max_xr(ixr,0)<=min_max_xr(ixr,1))) {
+	std::cerr << "The lower bound of the domain of the Kriging Model must be less than or equal to the upper bound of the domain of the Kriging Model\n";
+	assert(min_max_xr(ixr,0)<=min_max_xr(ixr,1));
+      }
+    //printf("lower_bounds = [%g",min_max_xr(0,0));
+    //for(int ixr=1; ixr<numVarsr; ++ixr)
+    //printf(", %g",min_max_xr(ixr,0));
+    //printf("]^T, upper_bounds = [%g",min_max_xr(0,1));
+    //for(int ixr=1; ixr<numVarsr; ++ixr)
+    //printf(", %g",min_max_xr(ixr,1));
+    //printf("]^T\n");
+    sdBuild.setUnscaledDomainSize(min_max_xr);
+  }
+
+  //printf("KrigingModel constructor should have just written out domain bounds\n");
+
+  param_it = params.find("dimension_groups");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    MtxInt dim_groups(numVarsr,1);
+    if(dim_groups.putCols(param_it->second,0)) {
+      std::cerr << "If you specify dimension_groups for any dimensions, "
+		<< "you must specify groups\nfor all dimensions. If you "
+		<< "don't want some of the dimensions to be grouped\n"
+		<< "with other dimensions during scaling, give each of "
+		<< "them their own group." << std::endl;
+      assert(false);
+    }
+    sdBuild.setDimGroups(dim_groups);
+  }
+
+  scaler.scaleToDefault(); //scale outputs to -0.5<=Y<=0.5 and scale
+  //real inputs to volume 1 hyper-rectangle centered at 0 if real
+  //input dimensions are locked or the unit hypercube centered at 0 if
+  //no dimensions are locked.  The scaling is done to let us define
+  //the feasible region simply (region is defined in create);
+
+  if(buildDerOrder==0) {
+    sdBuild.getY(Yall);
+    Yall.reshape(numPoints,1);
+  }
+  else if(buildDerOrder==1) {
+    sdBuild.getUpToDerY(Yall,1);
+    Yall.reshape(numEqnAvail,1);
+    //Yall is now a column vector that contains
+    //[y0, dy_0/dxr_0, ..., dy_0/dxr_{numVarsr-1}, y1, dy_1/dxr_0, ..., y2, ...
+    // y_{numPoints-1}, dy_{numPoints-1}/dxr_0, ...,
+    // dy_{numPoints-1}/dx_{numVarsr-1}]^T
+  }
+
+  // *************************************************************
+  // this starts the input section about optimizing or directly
+  // specifying correlation lengths, it must come after the
+  // scaling section
+  // *************************************************************
+
+  // current options are none (fixed correl) | sampling (guess) | local |
+  // global | global_local
+  optimizationMethod = "global"; //the default
+  //optimizationMethod = "none"; //the default
+  param_it = params.find("optimization_method");
+  if (param_it != params.end() && param_it->second.size() > 0)
+    optimizationMethod = param_it->second;
+
+  if(optimizationMethod.compare("none")==0)
+    maxTrials=1;
+  else if(optimizationMethod.compare("local")==0)
+    maxTrials=20;
+  else if(optimizationMethod.compare("sampling")==0)
+    maxTrials=2*numVarsr+1;
+  else if(optimizationMethod.compare("global")==0)
+    maxTrials = 10000;
+  else if(optimizationMethod.compare("global_local")==0) {
+    maxTrials = 10000; //ensure it has non-zero as a fail safe but this
+    //shouldn't be used
+    maxTrialsGlobal = 500;
+    maxTrialsLocal = 20;
+  }
+  else{ //error checking the input
+    std::cerr << "KrigingModel() unknown optimization_method [" << optimizationMethod << "]  aborting\n";
+    assert(false);
+  }
+
+  //std::cout << "optimization_method=\"" << optimizationMethod << "\"\n";
+
+  //numStarts is the number of starting locations in a multi-start local search
+  numStarts=1; //default is a single starting location
+  param_it = params.find("num_starts");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    numStarts = std::atoi(param_it->second.c_str());
+    if(numStarts<1) {
+      std::cerr << "You can't specify fewer than one starting location "
+		<< "for the optimization\nof correlation lenghts"
+		<< std::endl;
+      assert(false);
+    }
+  }
+
+  if(!((numStarts==1)||(optimizationMethod.compare("local")==0))) {
+    std::cerr << "Local optimization is the only optimization method for Kriging that uses the \"num_starts\" key word. Check your input file for errors.\n";
+    assert(false);
+  }
+
+  //std::cout << "num_starts=" << numStarts << "\n";
+
+
+  // does the user want to specify correlation lengths directly?
+  ifUserSpecifiedCorrLengths=false; //the default is no
+  param_it = params.find("correlation_lengths");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    ifUserSpecifiedCorrLengths=true;
+    //printf("User specifying correlation lengths\n"); fflush(stdout);
+
+    // make sure that the user didn't
+    // * say they want to global optimize __AND__
+    // * specify correlation lengths
+    if(optimizationMethod.compare("global")==0) {
+      std::cerr << "You can't both \n (A) use the global optimization method to choose, and \n (B) directly specify \n correlation lengths for the Kriging model.\n";
+      assert(false);
+    }
+    else if(optimizationMethod.compare("global_local")==0) {
+      //they can't coarse global followed by local either
+      std::cerr << "You can't both \n (A) use the coarse global polished by local optimization method to choose, and \n (B) directly specify \n correlation lengths for the Kriging model.\n";
+      assert(false);
+    }
+    else if(optimizationMethod.compare("sampling")==0) {
+      // this is only the default number of samples/maxTrials; the user can
+      // still overide this below
+      maxTrials+=1;
+    }
+
+    natLogCorrLen.newSize(numVarsr,1); //allocate space
+
+    //read the correlation lengths in from the string
+    if(natLogCorrLen.putCols(param_it->second,0)) {
+      std::cerr << "The specified correlation lengths had the wrong "
+		<< "number of input dimensions." << std::endl;
+      assert(false);
+    }
+    // "natLogCorrLen" currently holds the unscaled correlation LENGTHS, not
+    // the natural log of the scaled correlation length, we need to fix that
+    // but first we need to check the input for errors
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      if(!(natLogCorrLen(ixr,0)>0.0)) {
+	std::cerr << "For the Kriging Model, correlation lengths must be strictly positive\n.";
+	assert(false);
+      }
+
+    //printf("unscaled corr lens = [%12.6g",natLogCorrLen(0,0));
+    //for(int ixr=1; ixr<numVarsr; ++ixr)
+    //printf(", %12.6g",natLogCorrLen(ixr,0));
+    //printf("]\n");
+
+    scaler.scaleXrDist(natLogCorrLen); //scale the lengths
+    //scaler.scaleXrOther(natLogCorrLen); //error
+    //printf("scaled corr lens = [%12.6g",natLogCorrLen(0,0));
+    //for(int ixr=1; ixr<numVarsr; ++ixr)
+    // printf(", %12.6g",natLogCorrLen(ixr,0));
+    //printf("]\n");
+    //fflush(stdout);
+
+    //compute the natural log of the correlation lengths
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      natLogCorrLen(ixr,0)=std::log(natLogCorrLen(ixr,0));
+
+    natLogCorrLen.reshape(numVarsr,1);
+    //natLogCorrLen will be the first of the initial iterates (guesses), this happens in the create() function below
+  }
+  //printf("If user specified correlationlengths we should have just printed them\n");
+
+  // maximum objective evals for optimization or guess
+  param_it = params.find("max_trials");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    maxTrials = std::atoi(param_it->second.c_str());
+  }
+
+  if(!(maxTrials > 0)) {
+    std::cerr << "You can't specify a maximum number of trials that is "
+	      << "less than or equal\nto zero." << std::endl;
+    assert(false);
+  }
+
+  //printf("maxTrials=%d\n",maxTrials);
+
+
+  // *************************************************************
+  // this starts the input section about the trend function
+  // *************************************************************
+  polyOrderRequested = 2;
+  ifReducedPoly=false;
+  param_it = params.find("order");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    polyOrderRequested = std::atoi(param_it->second.c_str());
+    //ssstd::cerr << "polyOrderRequested=" << polyOrderRequested << std::endl;
+    if(!(polyOrderRequested >= 0)) {
+      std::cerr << "You can't use a trend function with a polynomial "
+		<< "order less than zero." << std::endl;
+      assert(false);
+    }
+  }
+  else{
+    //if they don't specify a polynomial order use a main effects
+    //polynomial with order 2 for the trend function, (if they do
+    //specify a polynomial order assume they mean a full polynomial
+    //order unless they specify that it's a reduced_polynomial)
+    ifReducedPoly=true;
+  }
+  numTrend.newSize(polyOrderRequested+1,1);
+
+  //cout << "order=" << polyOrder << "\n";
+
+  //polyOrder = 2; //for debug
+  //main_effects_poly_power(Poly, numVarsr, polyOrder); //for debug
+  //commented out for debug
+
+  param_it = params.find("reduced_polynomial");
+  if (param_it != params.end() && param_it->second.size() > 0)
+    if((std::atoi(param_it->second.c_str()))!=0)
+      ifReducedPoly=true;
+
+  //cout << "ifReducedPoly=" << ifReducedPoly << "\n";
+
+  if(ifReducedPoly) {
+    for(polyOrder=0; polyOrder<=polyOrderRequested; ++polyOrder)
+      numTrend(polyOrder,0)=polyOrder*numVarsr+1;
+    main_effects_poly_power(Poly, numVarsr, polyOrderRequested);
+  }
+  else{
+    for(polyOrder=0; polyOrder<=polyOrderRequested; ++polyOrder)
+      numTrend(polyOrder,0)=num_multi_dim_poly_coef(numVarsr, polyOrder);
+    multi_dim_poly_power(Poly, numVarsr, polyOrderRequested);
+  }
+
+
+  // ********************************************************************
+  // this starts the section about the choice of correlation functions
+  // need to do build derivative order before this
+  // ********************************************************************
+  corrFunc=DEFAULT_CORR_FUNC;
+
+  //POW_EXP_CORR_FUNC
+  powExpCorrFuncPow=0.0; //only 1.0<=powExpCorrFunc<=2.0 are allowed
+  //later if corrFunc==POW_EXP_CORR_FUNC and powExpCorrFuncPow==0.0 we know
+  //we have an error
+  param_it = params.find("powered_exponential");
+  if(param_it != params.end() && param_it->second.size() > 0) {
+    if(corrFunc!=DEFAULT_CORR_FUNC) {
+      std::cerr << "You can only specify one correlation function\n";
+      assert(false);
+    }
+    corrFunc=POW_EXP_CORR_FUNC;
+    powExpCorrFuncPow=std::atof(param_it->second.c_str());
+    if(!((1.0<=powExpCorrFuncPow)&&(powExpCorrFuncPow<=2.0))){
+      std::cerr << "The powered exponential correlation function must have 1.0<=power<=2.0\n";
+      assert(false);
+    }
+    //need to require 1<powExpCorrFuncPow if first derivatives are used
+    //(otherwise no derivative is continuous at build points
+    //will need to require powExpCorrFuncPow==2 of 2nd or higher order
+    //derivatives are used
+    if(powExpCorrFuncPow==1.0)
+      corrFunc=EXP_CORR_FUNC;
+    else if(powExpCorrFuncPow==2.0)
+      corrFunc=GAUSSIAN_CORR_FUNC;
+  }
+
+  //MATERN_CORR_FUNC
+  maternCorrFuncNu=0.0; //only 0.5, 1.5, 2.5, and infinity will be allowed
+  //later if corrFunc==MATERN_CORR_FUNC and maternCorrFuncNu=0.0 we know
+  //we have an error
+  param_it = params.find("matern");
+  if(param_it != params.end() && param_it->second.size() > 0) {
+    if(corrFunc!=DEFAULT_CORR_FUNC) {
+      std::cerr << "You can only specify one correlation function\n";
+      assert(false);
+    }
+    if(param_it->second.compare("infinity")==0) {
+      corrFunc=GAUSSIAN_CORR_FUNC;
+      //matern nu=infinty is the Gaussian correlation function
+    }
+    else{
+      corrFunc=MATERN_CORR_FUNC;
+      maternCorrFuncNu=std::atof(param_it->second.c_str());
+      if(!((maternCorrFuncNu==0.5)||(maternCorrFuncNu==1.5)||
+	   (maternCorrFuncNu==2.5))) {
+	//could allow more later if 3rd+ order derivatives are enabled later
+	std::cerr << "For the Matern correlation function the only allowed values for nu are 0.5, 1.5, 2.5, and infinity\n";
+	assert(false);
+      }
+      if(maternCorrFuncNu==0.5) {
+	corrFunc=EXP_CORR_FUNC; //matern nu=0.5 is the exponential correlation function
+	//need to disallow maternCorrFuncNu=0.5 if gradients or higher order derivatives are used to construct the Kriging model
+      }
+      //need to disallow maternCorrFuncNu=1.5 it hessians or higher order derivatives are used to construct the Kriging model
+    }
+  }
+
+  if(corrFunc==DEFAULT_CORR_FUNC)
+    corrFunc=GAUSSIAN_CORR_FUNC;
+
+  // *************************************************************
+  // this starts the input section HOW to bound the condition
+  // number, this determines which derivatives of the constraint
+  // function can be computed analytically so handle that here too
+  // *************************************************************
+  //constraintType="rcond"; //rcond is now the only option for type of
+  //constraint against ill conditioning
+  numConFunc=1;
+
+  //convert to the Dakota bitflag convention for derivative orders
+  int num_analytic_obj_ders_in=0; //analytical derivatives have been removed
+  int num_analytic_con_ders_in=0; //analytical derivatives have been removed
+  maxObjDerMode=(static_cast<int>(std::pow(2.0,num_analytic_obj_ders_in+1)))-1; //analytical gradients of objective function
+  maxConDerMode=(static_cast<int> (std::pow(2.0,num_analytic_con_ders_in+1)))-1; //analytical gradients of constraint function(s)
+
+  maxCondNum=std::pow(1024.0,4);
+
+  // *************************************************************
+  // this starts the input section about the nugget which can be
+  // used to smooth the data and also decrease the condition
+  // number
+  // *************************************************************
+
+  ifChooseNug = false;
+  //ifChooseNug = true;
+  ifAssumeRcondZero=false;
+  param_it = params.find("find_nugget");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    ifChooseNug = true;
+    int zero_or_one = std::atoi(param_it->second.c_str());
+    if(zero_or_one==0)
+      ifAssumeRcondZero=true;
+  }
+  //ifChooseNug = true ; std::cout << "ifChooseNug=" << ifChooseNug << "\n";
+
+  // fixed value for now
+  nug = 0.0; //default
+  ifPrescribedNug=false;
+  param_it = params.find("nugget");
+  if (param_it != params.end() && param_it->second.size() > 0) {
+    if(!(ifChooseNug==false)) {
+      std::cerr << "You can do at most 1 of the following (A) auto-select "
+		<< "the nugget\n(approximately the minimum needed to "
+		<< "satisfy the condition number bound)\n(B) directly "
+		<< "specify a nugget.  The default is not to use a nugget "
+		<< "at all\n(i.e. use a nugget of zero)." << std::endl;
+      assert(false);
+    }
+    nug = std::atof(param_it->second.c_str());
+    if(!(nug >= 0.0)) {
+      std::cerr << "The nugget must be greater than or equal to zero."
+		<< std::endl;
+      assert(false);
+    }
+    ifPrescribedNug=true;
+  }
+
+  // *************************************************************
+  // this ends the input parsing now finish up the prep work
+  // *************************************************************
+  preAllocateMaxMemory(); //so we don't have to constantly dynamically
+  //allocate, the SurfMat class can use a subset of the allocated memory
+  //without using dynamic reallocation
+
+  // precompute and store the trend function for all build points
+  if(buildDerOrder==0) //for Kriging
+    eval_trend_fn(Gall, XR);
+  else if(buildDerOrder>=1) { //for GEK
+    //actually this is generic to higher order derivative enhanced Kriging
+    //(e.g. Hessian Enhanced Kriging) provided that Der is appropriately
+    //defined
+    eval_der_trend_fn(Gall, Der, XR);
+  } else{
+    std::cerr << "bogus buildDerOrder=" << buildDerOrder
+	      << " in the constructor when evaluating Gall" << std::endl;
+    assert(false);
+  }
+
+  if((ifChooseNug==true)||(ifPrescribedNug==true)) {
+    //if we're using a nugget then we aren't using pivoted cholesky to
+    //select an optimal subset of points, that means that the order of
+    //points aren't going to change so we'll set Y and Gtran to what
+    //we know they need to be
+    iPtsKeep.newSize(numPoints,1);
+    for(int ipt=0; ipt<numPoints; ++ipt)
+      iPtsKeep(ipt,0)=ipt;
+
+    Y.copy(Yall);
+
+    //polyOrder=polyOrderRequested;
+    nTrend=numTrend(polyOrderRequested,0);
+    Gtran.newSize(numEqnAvail,nTrend);
+    for(int itrend=0; itrend<nTrend; ++itrend)
+      for(int i=0; i<numEqnAvail; ++i)
+	Gtran(i,itrend)=Gall(itrend,i);
+
+    if(buildDerOrder==0)
+      numExtraDerKeep=0;
+    else if(buildDerOrder==1)
+      numExtraDerKeep=numVarsr;
+    else{
+      std::cerr << "buildDerOrder=" << buildDerOrder
+		<< " in void KrigingModel::nuggetSelectingCholR(); "
+		<< "for Kriging buildDerOrder must be 0; "
+		<< "for Gradient Enhanced Kriging buildDerOrder must be 1; "
+		<< "Higher order derivative enhanced Kriging "
+		<< "(e.g Hessian Enhanced Kriging) has not been implemented"
+		<< std::endl;
+      assert(false);
+    }
+    numPointsKeep=numPoints;
+    numRowsR=numEqnAvail;
+  }
+
+  gen_Z_matrix();  //initializes deltaXR and Z matrices (what the Z
+  // matrix contains depends on the choose of correlation function but
+  // as of 2012.06.25 all correlation functions involve an
+  // coefficient*exp(Z^T*theta) (reshaped to the lower triangular part of R)
+  // for the powered Exponential family of correlation functions that
+  // coefficient is 1.0, for Matern 1.5 and Matern 2.5 correlation functions
+  // it's not 1.0 and we only do the multiplcation when the coefficient isn't
+  // 1.0 to save computation.
+
+  //printf("completed the KrigingModel constructor\n"); fflush(stdout);
+}
+
+void KrigingModel::create()
+{
+  //printf("entered create()\n"); fflush(stdout);
+
+  prevObjDerMode=prevConDerMode=0; //tells us not to reuse previous work used
+  //to calculate the objective, constraints and their derivatives the first
+  //time they are asked for
+  prevTheta.newSize(numTheta,1);
+  prevTheta.zero(); //not necessary just useful to debug
+
+  //printf("KM.create():1: nug=%g\n",nug);
+
+  // -
+  // solve the optimization problem for the correlations
+  // -
+
+  //printf("numVarsr=%d\n",numVarsr); fflush(stdout);
+  OptimizationProblem opt(*this, numVarsr, numConFunc);
+
+
+  // set the bounds for the plausible region for correlation lengths
+  // (assumes input space has a volume of 1, and data points are
+  // uniformly distributed)
+  aveDistBetweenPts=std::pow(numPoints,-1.0/numVarsr);
+
+  // note: we should explore different bounds on the correlation lengths
+  // for different choices of the correlation function, but this has not
+  // been done yet, the "procedure" for determining how far the lengths
+  // should extend is to say that X% probability mass is located a
+  // certain distance away (5% at 16 neighbors for the upper bound, and
+  // for the lower bound you want the nearest neighbor to be
+  // "essentially uncorrelated" while halfway between nearest neigbors
+  // is slightly correlated)
+
+  // For the maximum correlation length = aveDistBetweenPts*8.0
+  // the Gaussian Correlation function (the original one this GP a.k.a.
+  // Kriging model was developed for) has about ~5% confidence (2 std
+  // devs away) in what points 16 neighbors away have to say. If points
+  // are correlated well at even greater distances then either
+  // * that same information will be contained in nearby points OR
+  // * you shouldn't be using a Gaussian process error model
+  double max_corr_length = aveDistBetweenPts*8.0;
+  maxNatLogCorrLen=std::log(max_corr_length);
+
+  // For the minimum correlation length = aveDistBetweenPts/4.0
+  // the Gaussian Correlation function (the original one this GP a.k.a.
+  // Kriging model was developed for) has about ~5% confidence (2 std
+  // midway between neighboring points... i.e. you're 4 std devs away
+  // from your nearest neighbor so all sample points are treated as being
+  // essentially uncorrelated
+  double min_corr_length = aveDistBetweenPts/4.0;
+  minNatLogCorrLen=std::log(min_corr_length);
+
+  //Choose dead center (in log(correlation length)) of the feasible region
+  //as the default initial guess for the Gaussian Process error model
+  double init_guess=0.5*(maxNatLogCorrLen+minNatLogCorrLen);
+
+  ///set the bounds and the initial iterates
+  if(ifUserSpecifiedCorrLengths==true) {
+    // the first guess is what the user told us he/she wanted to use
+    for(int ixr=0; ixr<numVarsr; ++ixr) {
+      opt.lower_bound(ixr, minNatLogCorrLen);
+      opt.upper_bound(ixr, maxNatLogCorrLen);
+      opt.initial_iterate(ixr, natLogCorrLen(ixr,0));
+    }
+    // the second guess is the center of the small feasible region
+    MtxDbl the_second_guess(numVarsr,1);
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      the_second_guess(ixr,0)=init_guess;
+    opt.add_initial_iterates(the_second_guess);
+  } else {
+
+    // since the user didn't specify an initial guess we will use the center
+    // of the small feasible region as our first initial guess
+    for(int ixr=0; ixr< numVarsr; ++ixr) {
+      opt.lower_bound(ixr, minNatLogCorrLen);
+      opt.upper_bound(ixr, maxNatLogCorrLen);
+      opt.initial_iterate(ixr, init_guess);
+    }
+  }
+
+  // add a binning optimal (read as space filling) random design with
+  // 2*numVars more guesses
+  // bins are the endpoints of a randomly rotated axis
+  MtxDbl axes_of_guesses(numVarsr,2*numVarsr);
+  gen_rand_axis_bin_opt_samples_0to1(axes_of_guesses,numVarsr);
+  for(int iguess=0; iguess<2*numVarsr; ++iguess) {
+    for(int ixr=0; ixr<numVarsr; ++ixr) {
+      axes_of_guesses(ixr,iguess)=(maxNatLogCorrLen-minNatLogCorrLen)*axes_of_guesses(ixr,iguess)+minNatLogCorrLen;
+    }
+  }
+  opt.add_initial_iterates(axes_of_guesses);
+
+  //choose the optimizer you want to use
+  if(optimizationMethod.compare("none")==0) {
+    natLogCorrLen.resize(numVarsr,1);
+    opt.retrieve_initial_iterate(0,natLogCorrLen);
+  }
+  else{
+    if(optimizationMethod.compare("local")==0) {
+      //local optimization
+      if(numStarts==1)
+	//from a single starting location
+	opt.conmin_optimize();
+      else{
+	//doing multi-start local optimization
+	opt.multistart_conmin_optimize(numStarts);
+      }
+    }
+    else if(optimizationMethod.compare("global")==0)
+      //global optimization via the "DIvision of RECTangles" method
+      opt.direct_optimize();
+    else if(optimizationMethod.compare("sampling")==0)
+      //randomly generate candidates and pick the best guess
+      opt.best_guess_optimize(maxTrials);
+    else if(optimizationMethod.compare("global_local")==0){
+      //a coarse global optimization that is polished by
+      //local optimization
+      maxTrials=maxTrialsGlobal;
+      opt.direct_optimize();
+      natLogCorrLen = opt.best_point();
+      maxTrials=maxTrialsLocal;
+      opt.conmin_optimize();
+    }
+    else{
+      std::cerr << "KrigingModel:create() unknown optimization_method [" << optimizationMethod << "]\naborting" << std::endl;
+      assert(false);
+    }
+    natLogCorrLen = opt.best_point();
+  }
+
+  MtxDbl corr_len(numVarsr,1);
+  for(int ixr=0; ixr<numVarsr; ++ixr)
+    corr_len(ixr,0)=std::exp(natLogCorrLen(ixr,0));
+  correlations.newSize(numVarsr,1);
+  get_theta_from_corr_len(correlations,corr_len);
+
+  //printf("}\n");
+
+  //printf("scaled correlations=[%12.6g",correlations(0,0));
+  //for(int ixr=1; ixr<numVarsr; ++ixr)
+  //printf(", %12.6g",correlations(ixr,0));
+  //printf("]\n");
+
+  masterObjectiveAndConstraints(correlations, 1, 0);
+
+  //keep only the "optimal" subset of trend basis function in Poly that was
+  //selected by the pivoted Cholesky factorization of G*R^-1*G^
+  if(nTrend<numTrend(polyOrderRequested,0)) {
+    //for this to work, the basis function indicices in iTrendKeep must
+    //be in monotonically increasing order
+
+    //we are guaranteed to keep the constant term of the trend function so
+    //start loop from 1 not zero
+    for(int itrend=1; itrend<nTrend; ++itrend) {
+      int isrc=iTrendKeep(itrend,0);
+      if(itrend<isrc)
+	for(int ixr=0; ixr<numVarsr; ++ixr)
+	   Poly(ixr,itrend)=Poly(ixr,isrc);
+    }
+
+    //now reduce the size of Poly
+    Poly.resize(numVarsr,nTrend);
+  }
+
+  //determine the maximum total order of any term in the part of the
+  //trend that was retained
+  polyOrder=Poly(0,nTrend-1);
+  for(int ixr=1; ixr<numVarsr; ++ixr)
+    polyOrder+=Poly(ixr,nTrend-1);
+
+
+
+  //make a reordered copy of (the retained portion of) XR for evaluation speed
+  XRreorder.newSize(numVarsr,numPointsKeep);
+  for(int ipt=0; ipt<numPointsKeep; ++ipt) {
+    int isrc=iPtsKeep(ipt,0);
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      XRreorder(ixr,ipt)=XR(ixr,isrc);
+  }
+
+  if(outputLevel >= NORMAL_OUTPUT) {
+    std::cout << model_summary_string();
+    //std::cout << std::endl;
+  }
+
+
+  //variables whose values needed to be retained between sequential call to masterObjectiveAndConstraints for precompute and store strategy to work
+  prevObjDerMode=prevConDerMode=0;
+
+  //deallocate matrices we no longer need after emulator has been created
+  //these were made member variables (instead of local variables) to avoid
+  //the cost of dynamic allocation and deallocation each cycle of the
+  //optimization of the correlation parameters
+  scaleRChol.clear(); //matrix
+  sumAbsColR.clear(); //vector
+  oneNormR.clear(); //vector
+  lapackRcondR.clear(); //vector
+  rcondDblWork.clear();  //vector
+  rcondIntWork.clear(); //vector
+  Yall.clear(); //vector
+  Gall.clear(); //matrix
+  Gtran.clear(); //matrix
+  iTrendKeep.clear(); //vector
+  Z.clear(); //matrix
+  Ztran_theta.clear(); //vector
+  deltaXR.clear(); //matrix
+  R.clear(); //matrix
+  G_Rinv_Gtran.clear(); //matrix
+  G_Rinv_Gtran_Chol_Scale.clear(); //vector
+  G_Rinv_Gtran_Chol_DblWork.clear(); //vector
+  G_Rinv_Gtran_Chol_IntWork.clear(); //vector
+  G_Rinv_Y.clear(); //vector
+  eps.clear(); //vector
+  prevTheta.clear(); //vector
+  con.clear(); //vector
+}
+
+std::string KrigingModel::get_corr_func() const {
+  std::ostringstream oss;
+
+  switch(corrFunc) {
+  case GAUSSIAN_CORR_FUNC:
+    oss << "Gaussian";
+    break;
+  case EXP_CORR_FUNC:
+    oss << "exponential";
+    break;
+  case POW_EXP_CORR_FUNC:
+    oss << "powered exponential with power=" << powExpCorrFuncPow;
+    break;
+  case MATERN_CORR_FUNC:
+    oss << "Matern " << static_cast<int>(maternCorrFuncNu*2.0) << "/2";
+    break;
+  default:
+    std::cerr << "unknown correlation function enumerated as " << corrFunc
+	      << std::endl;
+    assert(false);
+  }
+  return (oss.str());
+}
+
+
+std::string KrigingModel::model_summary_string() const {
+  MtxDbl temp_out_corr_lengths(numVarsr,1);
+  get_corr_len_from_theta(temp_out_corr_lengths,correlations);
+  scaler.unScaleXrDist(temp_out_corr_lengths);
+
+  //printf("numPoints=%d numTrend=%d numPointsKeep=%d numWholePointsKeep=%d numExtraDerKeep=%d\n",numPoints,numTrend(polyOrder,0),numPointsKeep,numWholePointsKeep,numExtraDerKeep);
+
+  std::ostringstream oss;
+  oss << "--- Surfpack Kriging Diagnostics ---\n";
+  if(buildDerOrder==0)
+    oss << "KM: #real inputs=" << numVarsr << "; #pts=" << numPoints
+	<< "; used " << numPointsKeep << "/" << numPoints << " pts;\n";
+  else if(buildDerOrder==1)
+    oss << "GEK: #real inputs=" << numVarsr << "; #pts=" << numPoints
+	<< "; #eqns=" << numEqnAvail << "; used "
+	<< numRowsR << "/" << numEqnAvail << " eqns;\n";
+  else{
+    oss << "error std::string KrigingModel::model_summary_string() const\n"
+	<< "buildDerOrder=" << buildDerOrder << "; it should be 0 for Kriging"
+	<< " or 1 for Gradient Enhanced Kriging (GEK);"
+	<< " the model_summary_string() function will need to be modified "
+	<< "to handle other build derivative orders.\n";
+  }
+  oss << "using the ";
+  if(corrFunc==GAUSSIAN_CORR_FUNC)
+    oss << "Gaussian";
+  else if(corrFunc==EXP_CORR_FUNC)
+    oss << "exponential";
+  else if(corrFunc==POW_EXP_CORR_FUNC)
+    oss << "powered exponential (with power = " << powExpCorrFuncPow << ")";
+  else if(corrFunc==MATERN_CORR_FUNC)
+    oss << "Matern " << maternCorrFuncNu;
+  else{
+    std::cerr << "unknown corr func in model_summary_string()" << std::endl;
+    assert(false);
+  }
+  oss << " correlation function with (unscaled)\n"
+      << "Correlation lengths=[" << temp_out_corr_lengths(0,0);
+  for(int ixr=1; ixr<numVarsr; ++ixr)
+    oss << ", " << temp_out_corr_lengths(ixr,0);
+  oss << "]^T\nfound by the \"" << optimizationMethod
+      << "\" optimization_method;\nunadjusted variance="
+      << estVarianceMLE * scaler.unScaleFactorVarY()
+      << "; \"per equation\" log(likelihood)=" << likelihood << ";\n"
+      << "rcond(R)=" << rcondR << "; rcond(G_Rinv_Gtran)="
+      << rcond_G_Rinv_Gtran << "; [if either rcond is less\n"
+      << "than 2^-40 (approx 9.095*10^-13) then the matrix is ill-conditioned "
+      << "and\nthat \"voids the warranty\" of the Kriging Model]; nugget="
+      << nug << ".  A ";
+  if(polyOrder>1) {
+    if(ifReducedPoly==true)
+      oss << "reduced_";
+    else oss <<"full ";
+  }
+  oss << "polynomial\nof order " << polyOrderRequested << " (with "
+      << numTrend(polyOrderRequested,0) << " terms) was requested "
+      << "for the trend function; the build\ndata was ";
+  if(nTrend<numTrend(polyOrderRequested,0) )
+    oss << "NOT ";
+  oss << "sufficient to use the requested trend function; "
+      << "the highest total\npolynomial order of any term in the "
+      << "utlized trend function is " << polyOrder << ";\n"
+      << "for SCALED inputs and outputs the utilized trend function is\n"
+      << "betaHat^T*g(x)=";
+  int nterm_on_this_line=0;
+  for(int itrend=0; itrend<nTrend; ++itrend) {
+    ++nterm_on_this_line;
+    oss << betaHat(itrend,0);
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      if(Poly(ixr,itrend)>0) {
+	oss << "*x" << ixr;
+	if(Poly(ixr,itrend)>1)
+	  oss << "^" << Poly(ixr,itrend);
+      }
+    if(itrend<nTrend-1) {
+      oss << " ";
+      if(betaHat(itrend+1,0)>=0.0)
+	oss << "+ ";
+      if(nterm_on_this_line==3) {
+	oss << "...\n               ";
+	nterm_on_this_line=0;
+      }
+    }
+  }
+  oss << "\n------------------------------------\n";
+  return (oss.str());
+}
+
+void KrigingModel::preAllocateMaxMemory() {
+  //this preallocates the maximum sizce of arrays whose size depends on how many equations were discarded by pivoted Cholesky and they could possibly be allocated to a different size than their maximum the first time they are allocated.
+
+  nTrend=numTrend(polyOrderRequested,0);
+  Y.newSize(numEqnAvail,1);
+  Gtran.newSize(numEqnAvail,nTrend);
+  Rinv_Gtran.newSize(numEqnAvail,nTrend);
+  G_Rinv_Gtran.newSize(nTrend,nTrend);
+  G_Rinv_Gtran_Chol.newSize(nTrend,nTrend);
+  rhs.newSize(numEqnAvail,1);
+  betaHat.newSize(nTrend,1);
+  G_Rinv_Y.newSize(nTrend,1);
+  eps.newSize(numEqnAvail,1);
+  iPtsKeep.newSize(numPoints,1);
+  RChol.newSize(numEqnAvail,numEqnAvail);
+  int nrows = nTrend;
+  if((ifChooseNug==false)&&(ifPrescribedNug==false)&&(numEqnAvail>nTrend))
+    nrows=numEqnAvail;
+  scaleRChol.newSize(nrows,3);
+  lapackRcondR.newSize(nrows,1);
+
+  return;
+}
+
+// BMA TODO: combine these two functions?
+
+/// evaluate (y) the Kriging Model at a single point (xr)
+double KrigingModel::evaluate(const MtxDbl& xr)
+{
+  if(buildDerOrder==0) {
+    //you wouldn't want to do this for Gradient Enhanced Kriging
+    //i.e. if gradients of y were used as inputs
+    double singular_y;
+    if(scaler.isYSingular(0,singular_y))
+      return singular_y;
+  }
+
+  //assert( (numVarsr == xr.getNCols()) && (xr.getNRows() == 1) );
+  MtxDbl g(nTrend,1), r(numRowsR,1);
+
+  /*
+  printf("double evaluate()\n");
+  printf("xr=[%20.14g", xr(0,0));
+  for(int ixr=1; ixr<numVarsr; ++ixr)
+    printf(", %20.14g",xr(ixr,0));
+    printf("]^T\n");
+  */
+
+  if(scaler.isUnScaled()) {
+    eval_trend_fn(g, xr);
+    correlation_matrix(r, xr);
+  }
+  else{
+    MtxDbl xr_scaled(xr);
+    scaler.scaleXrOther(xr_scaled);
+    eval_trend_fn(g, xr_scaled);
+    correlation_matrix(r, xr_scaled);
+  }
+
+  double y = dot_product(g, betaHat) + dot_product(r, rhs);
+
+  //double yus=scaler.unScaleYOther(y);
+  //printf("y=%g yunscaled=%g\n",y,yus);
+  //return yus;
+
+  return (scaler.unScaleYOther(y));
+}
+
+
+/// evaluate (y) the Kriging Model at a collection of points (xr)
+MtxDbl& KrigingModel::evaluate(MtxDbl& y, const MtxDbl& xr)
+{
+  int nptsxr=xr.getNCols();
+  //printf("nptsxr=%d nvarsrxr=%d",nptsxr,xr.getNCols());
+
+  y.newSize(1,nptsxr);
+  if(buildDerOrder==0) {
+    //you wouldn't want to do this for Gradient Enhanced Kriging
+    //i.e. if gradients of y were used as inputs
+    double singular_y;
+    if(scaler.isYSingular(0,singular_y)) {
+      for(int ipt=0; ipt<nptsxr; ++ipt)
+	y(0,ipt)=singular_y;
+      return y;
+    }
+  }
+  //assert(numVarsr == xr.getNRows());
+  MtxDbl g(nTrend, nptsxr), r(numRowsR, nptsxr);
+
+  if(scaler.isUnScaled()) {
+    eval_trend_fn(g, xr);
+    correlation_matrix(r, xr);
+  }
+  else{
+    MtxDbl xr_scaled(xr);
+    scaler.scaleXrOther(xr_scaled);
+    eval_trend_fn(g, xr_scaled);
+    correlation_matrix(r, xr_scaled);
+  }
+
+  //y=0.0*y+1.0*betaHat^T*g => y = betaHat^T*g
+  matrix_mult(y, betaHat, g, 0.0, 1.0,'T','N');
+
+  //y=1.0*y+1.0*r*rhs where rhs=R^-1*(Y-G(XR)^T*betaHat), initial y=betaHat^T*g => y=betaHat^T*g+rhs^T*r
+  matrix_mult(y, rhs    , r, 1.0, 1.0,'T','N');
+
+  scaler.unScaleYOther(y);
+
+  //printf("y is correct for ValidateMain because it isn't being unscaled\n");
+
+  return y;
+}
+
+MtxDbl& KrigingModel::evaluate_d1y(MtxDbl& d1y, const MtxDbl& xr)
+{
+  int nptsxr=xr.getNCols();
+#ifdef __KRIG_ERR_CHECK__
+  assert((numVarsr == xr.getNRows())&&(0<nptsxr));
+#endif
+  d1y.newSize(numVarsr, nptsxr);
+  if(buildDerOrder==0) {
+    //you wouldn't want to do this for Gradient Enhanced Kriging
+    //i.e. if gradients of y were used as inputs
+    double singular_y;
+    if(scaler.isYSingular(0,singular_y)) {
+      d1y.zero();
+      return d1y;
+    }
+  }
+
+  /*
+  printf("evaluate_d1y()\n");
+  for(int ipt=0; ipt<numPoints; ++ipt) {
+    printf("XR(:,%3d)=[%12.6g",ipt,XR(0,ipt));
+    for(int ixr=1; ixr<numVarsr; ++ixr)
+      printf(", %12.6g",XR(ixr,ipt));
+    printf("]^T Y(%3d)=%12.6g\n",ipt,Y(0,ipt));
+  }
+  */
+
+  MtxDbl xr_scaled(xr);
+  if(~(scaler.isUnScaled())) {
+    //printf("scaling xr_scaled\n");
+    scaler.scaleXrOther(xr_scaled);
+  }
+
+  /*
+  printf("xr       =[%12.6g, %12.6g]\n",xr(0,0),xr(1,0));
+  printf("xr_scaled=[%12.6g, %12.6g]\n",xr_scaled(0,0),xr_scaled(1,0));
+  */
+
+  int nder=num_multi_dim_poly_coef(numVarsr,-1);
+  MtxInt der(numVarsr,nder);
+  multi_dim_poly_power(der,numVarsr,-1); //equivalent to der.identity();
+
+  evaluate_poly_der(d1y,flyPoly,derivBetaHat,Poly,der,betaHat,xr_scaled);
+
+  MtxDbl r(numRowsR,nptsxr);
+  correlation_matrix(r, xr_scaled);
+  //apply_nugget_eval(r);
+  MtxDbl d1r(numRowsR,nptsxr);
+  MtxDbl temp_vec(1,nptsxr);
+
+  for(int ider=0; ider<nder; ++ider) {
+
+    //find the single dimension we are taking the first derviative of
+    int ixr;
+    for(ixr=0; ixr<numVarsr; ++ixr)
+      if(der(ixr,ider)>0)
+	break;
+    //printf("ixr=%d ",ixr);
+#ifdef __KRIG_ERR_CHECK__
+    assert(ixr==ider);
+#endif
+
+    double d1y_unscale_factor=scaler.unScaleFactorDerY(ixr);
+    //printf("d1y_usf=%g\n",d1y_unscale_factor);
+
+    dcorrelation_matrix_dxI(d1r, r, xr_scaled, ixr);
+    matrix_mult(temp_vec,rhs,d1r,0.0,1.0,'T');
+
+    for(int ipt=0; ipt<nptsxr; ++ipt)
+      d1y(ider,ipt)=(d1y(ider,ipt)+temp_vec(0,ipt))*d1y_unscale_factor;
+  }
+  /*
+  printf("d1y(:,0)=[%g",d1y(0,0));
+  for(int ider=1; ider<numVarsr; ++ider)
+    printf(", %g",d1y(ider,0));
+  printf("]\n");
+  */
+  return d1y;
+}
+
+MtxDbl& KrigingModel::evaluate_d2y(MtxDbl& d2y, const MtxDbl& xr)
+{
+  int nptsxr=xr.getNCols();
+  int nder=num_multi_dim_poly_coef(numVarsr,-2);
+  d2y.newSize(nder,nptsxr);
+  if(buildDerOrder==0) {
+    double singular_y;
+    if(scaler.isYSingular(0,singular_y)) {
+      //you wouldn't want to do this for gradient based Kriging
+      //if gradients of y were used as inputs
+      d2y.zero();
+      return d2y;
+    }
+  }
+
+  MtxDbl xr_scaled(xr);
+  if(~(scaler.isUnScaled()))
+    scaler.scaleXrOther(xr_scaled);
+  //assert(numVarsr == xr.getNCols());
+
+  MtxInt der(numVarsr,nder);
+  MtxInt thisder(numVarsr,1);
+  multi_dim_poly_power(der,numVarsr,-2);
+
+  evaluate_poly_der(d2y,flyPoly,derivBetaHat,Poly,der,betaHat,xr_scaled);
+
+  MtxDbl r(numRowsR,nptsxr);
+  correlation_matrix(r, xr);
+  //apply_nugget_eval(r);
+  MtxDbl d1r(numRowsR,nptsxr);
+  MtxDbl d2r(numRowsR,nptsxr);
+  MtxDbl temp_vec(1,nptsxr);
+
+  for(int ider=0; ider<nder; ++ider) {
+    int ixr, jxr, ixrold=-1;
+
+    der.getCols(thisder,ider);
+    double d2y_unscale_factor=scaler.unScaleFactorDerY(thisder);
+    //std::cout << "thisder=[" << thisder(0,0) << ", " << thisder(1,0)
+    //<< "]^T unscalefactor=" << d2y_unscale_factor << std::endl;
+
+    //find the first dimension we are taking a first derviative of
+    for(ixr=0; ixr<numVarsr; ++ixr)
+      if(der(ixr,ider)>0)
+	break;
+
+    if(ixr!=ixrold) {
+      ixrold=ixr;
+      dcorrelation_matrix_dxI(d1r, r, xr_scaled, ixr);
+    }
+
+    //find the second dimension we are taking a first derivative of
+    if(der(ixr,ider)==2)
+      jxr=ixr;
+    else
+      for(jxr=ixr+1; jxr<numVarsr; ++jxr)
+	if(der(jxr,ider)>0)
+	  break;
+#ifdef __KRIG_ERR_CHECK__
+    assert(jxr<numVarsr);
+#endif
+
+    //dcorrelation_matrix_dxI(d2r, d1r, xr_scaled, jvar);
+    d2correlation_matrix_dxIdxJ(d2r, d1r, r, xr_scaled, ixr, jxr);
+    //std::cout << "ider=" << ider << " size(d2r)=[" << d2r.getNRows()
+    //	      << ", " << d2r.getNCols() << "]" << std::endl;
+    matrix_mult(temp_vec,rhs,d2r,0.0,1.0,'T','N');
+
+    for(int ipt=0; ipt<nptsxr; ++ipt)
+      d2y(ider,ipt)=(d2y(ider,ipt)+temp_vec(0,ipt))*d2y_unscale_factor;
+  }
+
+  return d2y;
+}
+
+
+
+/** matrix Ops evaluation of adjusted variance at a single point
+    adj_var=unadjvar*
+            (1-r^T*R^-1*r+(g-G*R^-1*r)^T*(G*R^-1*G^T)^-1*(g-G*R^-1*r))
+    on a point by point basis */
+double KrigingModel::eval_variance(const MtxDbl& xr)
+{
+#ifdef __KRIG_ERR_CHECK__
+  assert( (numVarsr==xr.getNRows()) && (xr.getNCols()==1) );
+#endif
+  MtxDbl g_minus_G_Rinv_r(nTrend,1), r(numRowsR,1);
+
+  double unscaled_unadj_var=estVarianceMLE;
+  if(scaler.isUnScaled()) {
+    eval_trend_fn(g_minus_G_Rinv_r, xr);
+    correlation_matrix(r, xr);
+  }
+  else{
+    unscaled_unadj_var*=scaler.unScaleFactorVarY();
+    MtxDbl xr_scaled(xr);
+    scaler.scaleXrOther(xr_scaled);
+    eval_trend_fn(g_minus_G_Rinv_r, xr_scaled);
+    correlation_matrix(r, xr_scaled);
+  }
+  //at this point g_minus_G_Rinv_r holds g
+
+  MtxDbl Rinv_r(numRowsR,1);
+  MtxDbl G_Rinv_Gtran_inv_g_minus_G_Rinv_r(nTrend,1);
+
+
+  solve_after_Chol_fact(Rinv_r,RChol,r);
+
+  matrix_mult(g_minus_G_Rinv_r,Rinv_Gtran,r,1.0,-1.0,'T','N');
+  //at this point g_minus_G_Rinv_r holds g-G*R^-*r (i.e. the name is correct)
+
+  solve_after_Chol_fact(G_Rinv_Gtran_inv_g_minus_G_Rinv_r,
+			G_Rinv_Gtran_Chol,g_minus_G_Rinv_r);
+
+
+  double adj_var=unscaled_unadj_var*
+    (1.0-dot_product(Rinv_r,r)+
+     dot_product(G_Rinv_Gtran_inv_g_minus_G_Rinv_r,g_minus_G_Rinv_r));
+  //if(!(adj_var>0.0)) {
+  //printf("adj_var=%g unscaled_unadj_var=%g rcondR=%g\n",adj_var,unscaled_unadj_var,rcondR);
+  //fflush(stdout);
+  //}
+  adj_var=std::fabs(adj_var); //hack to handle "negative zero" variance (numerical precision round off error)
+  if(adj_var<0.0) {
+    printf("NKM setting adj_var to zero adj_var=%g unadj_var=%g rcondR=%g\n",adj_var,unscaled_unadj_var,rcondR);
+    adj_var=0.0;
+  }
+  else if(adj_var==0.0)
+    printf("NKM adj_var is zero =%g\n",adj_var);
+  else if(!(adj_var>=0.0))
+    printf("double NKM_KrigingModel::eval_variance(...) adj_var=nan rcondR=%g\n",rcondR);
+
+  return adj_var;
+}
+
+/** Evaluate the adjusted variance for a collection of points using matrix
+    ops (i.e. BLAS and LAPACK) as much as possible)
+    adj_var=unadjvar*
+            (1-r^T*R^-1*r+(g-G*R^-1*r)^T*(G*R^-1*G^T)^-1*(g-G*R^-1*r))
+    on a point by point basis */
+MtxDbl& KrigingModel:: eval_variance(MtxDbl& adj_var, const MtxDbl& xr)
+{
+#ifdef __KRIG_ERR_CHECK__
+  assert(numVarsr==xr.getNRows());
+#endif
+  int nptsxr=xr.getNCols();
+  adj_var.newSize(1,nptsxr);
+  MtxDbl g_minus_G_Rinv_r(nTrend,nptsxr), r(numRowsR,nptsxr);
+
+  double unscaled_unadj_var=estVarianceMLE;
+  if(scaler.isUnScaled()) {
+    eval_trend_fn(g_minus_G_Rinv_r, xr);
+    correlation_matrix(r, xr);
+  }
+  else{
+    unscaled_unadj_var*=scaler.unScaleFactorVarY();
+    MtxDbl xr_scaled(xr);
+    scaler.scaleXrOther(xr_scaled);
+    eval_trend_fn(g_minus_G_Rinv_r, xr_scaled);
+    correlation_matrix(r, xr_scaled);
+  }
+  //right now g_minus_G_Rinv_r actually holds g
+
+  MtxDbl Rinv_r(numRowsR,nptsxr);
+  MtxDbl G_Rinv_Gtran_inv_g_minus_G_Rinv_r(nTrend,nptsxr);
+
+  solve_after_Chol_fact(Rinv_r,RChol,r);
+  matrix_mult(g_minus_G_Rinv_r,Rinv_Gtran,r,1.0,-1.0,'T','N');
+  //g_minus_G_Rinv_r now holds g-G*R^-1*r (i.e. it's name is correct)
+
+  solve_after_Chol_fact(G_Rinv_Gtran_inv_g_minus_G_Rinv_r,
+			G_Rinv_Gtran_Chol,g_minus_G_Rinv_r);
+
+  for(int ipt=0; ipt<nptsxr; ++ipt) {
+    //saved 2*nptsxr loops
+    adj_var(0,ipt)=1.0-r(0,ipt)*Rinv_r(0,ipt)+
+      g_minus_G_Rinv_r(0,ipt)*G_Rinv_Gtran_inv_g_minus_G_Rinv_r(0,ipt);
+
+    //looks a lot like matrix mult but only N^2 ops... it's the diagonal
+    //of a matrix matrix multiply
+    for(int iR=1; iR<numRowsR; ++iR)
+      adj_var(0,ipt)-=r(iR,ipt)*Rinv_r(iR,ipt);
+
+    //looks a lot like matrix mult but only N^2 ops ... it's the diagonal
+    //of a matrix matrix multiply
+    for(int itrend=1; itrend<nTrend; ++itrend)
+      adj_var(0,ipt)+=g_minus_G_Rinv_r(itrend,ipt)*
+	G_Rinv_Gtran_inv_g_minus_G_Rinv_r(itrend,ipt);
+
+    adj_var(0,ipt)*=unscaled_unadj_var;
+
+    if(adj_var(0,ipt)<0.0)
+      adj_var(0,ipt)=std::fabs(adj_var(0,ipt)); //zero to within round off and the magnitude of the negative value will give us an idea of how big round off is
+    else if(!(adj_var(0,ipt)>=0.0))
+      printf("MtxDbl& NKM_KrigingModel::eval_variance(...) adj_var(%d)=nan rcondR=%g\n",ipt,rcondR);
+  }
+
+  return adj_var;
+}
+
+/** set R=(R+nug*I), where the original R is the correlation matrix for the
+    data that the model is built from.  For GEK this generalizes to
+    R(i,i)=R(i,i)*(1+nug); Modifying the correlation matrix by the inclusion
+    of a nugget causes the KrigingModel to smooth the data, i.e. approximate
+    it rather than interpolate it (which is good if you know how big your
+    measurement noise is), it can also be used to fix an ill conditioned
+    correlation matrix.  The convention is that capital matrices are for
+    data the model is built from, lower case matrices are for arbitrary
+    points to evaluate the model at */
+void KrigingModel::apply_nugget_build() {
+  if(!(nug>0.0)) return;
+  //printf("applying nugget=%22.16g\n",nug);
+
+  int nrowsR=R.getNRows();
+#ifdef __KRIG_ERR_CHECK__
+  assert(nrowsR==R.getNCols());
+#endif
+
+  double one_plus_nug=1.0+nug;
+  for(int i=0; i<nrowsR; ++i)
+    R(i,i)*=one_plus_nug;
+
+  return;
+}
+
+// convert from correlation lengths to theta (a.k.a. correlation parameters)
+MtxDbl& KrigingModel::get_theta_from_corr_len(MtxDbl& theta,
+					      const MtxDbl& corr_len) const{
+  theta.newSize(numVarsr,1);
+  if(corrFunc==GAUSSIAN_CORR_FUNC)
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      theta(ixr,0)=0.5/(corr_len(ixr,0)*corr_len(ixr,0));
+  else if(corrFunc==EXP_CORR_FUNC) {
+#ifdef __KRIG_ERR_CHECK__
+    assert(buildDerOrder==0);
+#endif
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      theta(ixr,0)=1.0/corr_len(ixr,0);
+  }
+  else if(corrFunc==POW_EXP_CORR_FUNC) {
+#ifdef __KRIG_ERR_CHECK__
+    assert(buildDerOrder==0);
+#endif
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      theta(ixr,0)=1.0/
+	(powExpCorrFuncPow*std::pow(corr_len(ixr,0),powExpCorrFuncPow));
+  }
+  else if(corrFunc==MATERN_CORR_FUNC)
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      theta(ixr,0)=std::sqrt(2.0*maternCorrFuncNu)/corr_len(ixr,0);
+  else{
+    std::cerr << "unknown corrFunc in get_theta_from_corr_len()\n";
+    assert(false);
+  }
+  return theta;
+}
+
+// convert from theta (a.k.a. correlation parameters) to correlation lengths
+MtxDbl& KrigingModel::get_corr_len_from_theta(MtxDbl& corr_len,
+					      const MtxDbl& theta) const{
+  corr_len.newSize(numVarsr,1);
+  if(corrFunc==GAUSSIAN_CORR_FUNC)
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      corr_len(ixr,0)=std::sqrt(0.5/theta(ixr,0));
+  else if(corrFunc==EXP_CORR_FUNC) {
+#ifdef __KRIG_ERR_CHECK__
+    assert(buildDerOrder==0);
+#endif
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      corr_len(ixr,0)=1.0/theta(ixr,0);
+  }
+  else if(corrFunc==POW_EXP_CORR_FUNC) {
+#ifdef __KRIG_ERR_CHECK__
+    assert(buildDerOrder==0);
+#endif
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      corr_len(ixr,0)=
+	std::pow(powExpCorrFuncPow*theta(ixr,0),-1.0/powExpCorrFuncPow);
+  }
+  else if(corrFunc==MATERN_CORR_FUNC)
+    for(int ixr=0; ixr<numVarsr; ++ixr)
+      corr_len(ixr,0)=std::sqrt(2.0*maternCorrFuncNu)/theta(ixr,0);
+  else{
+    std::cerr << "unknown corrFunc in get_theta_from_corr_len()\n";
+    assert(false);
+  }
+  return corr_len;
+}
+
+
+
+
+/** the inline function
+    MtxDbl& KrigingModel::correlation_matrix(MtxDbl& r, const MtxDbl& xr) const
+    calls either
+    MtxDbl& KrigingModel::eval_kriging_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const (i.e. this function)
+    OR
+    MtxDbl& KrigingModel::eval_gek_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const
+
+    r (lower case r) is the Kriging correlation matrix between the
+    interpolation points and build data points, it used to EVALUATE but
+    not construct the emulator's Gaussian process error model
+    i.e. E(y(xr)|Y(XR))=betaHat^T*g(xr)+rhs^T*r  where
+    rhs=R^-1*(Y-G(XR)^T*betaHat)
+    choices for correlation function are gaussian, exponential,
+    powered exponential with 1<power<2, matern with nu=1.5 or 2.5
+    KRD wrote this */
+MtxDbl& KrigingModel::eval_kriging_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const
+{
+  if(buildDerOrder!=0) {
+    std::cerr << "You should only call eval_kriging_correlation_matrix when you want to evaluate regular Kriging (not GEK)\n";
+    assert(buildDerOrder==0);
+  }
+
+  int nptsxr=xr.getNCols(); //points at which we are evalutating the model
+#ifdef __KRIG_ERR_CHECK__
+  //  std::cerr<< "xr.getNRows()=" << xr.getNRows()
+  //	   << " numVarsr=" << numVarsr
+  //	   << " nptsxr=" << nptsxr << std::endl;
+
+  assert((xr.getNRows()==numVarsr)&&(0<nptsxr));
+#endif
+  r.newSize(numRowsR,nptsxr);
+  int i; //row index of the Kriging r matrix (also reorderd XR point index)
+  int j; //column index of the Kriging r matrix (also xr point index)
+  int k; //dimension index
+  double deltax;
+
+  if(corrFunc==GAUSSIAN_CORR_FUNC) {
+    // ******************************************************************
+    // the Gaussian Correlation function
+    // ******************************************************************
+    if(numVarsr==1) {
+      //special case for when there is only 1 input variable
+      double theta=correlations(0,0);
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(0,j)-XRreorder(0,i);
+	  r(i,j)=std::exp(-theta*deltax*deltax);
+	}
+    } else {
+      //general case there is more than 1 input variable
+      //even if nptsxr==1 outer looping once isn't a big performance hit
+      //so don't duplicate the code; smallest, i.e. k, loop is inside but
+      //that enables a single writing pass through the output array "r"
+      double sum_neg_theta_dx_squared;
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(0,j)-XRreorder(0,i);
+	  sum_neg_theta_dx_squared=-correlations(0,0)* //=- is correct
+	    deltax*deltax;
+	  for(k=1; k<numVarsr-1; ++k) {
+	    deltax=xr(k,j)-XRreorder(k,i);
+	    sum_neg_theta_dx_squared-=correlations(k,0)* //-= is correct
+	      deltax*deltax;
+	  }
+	  k=numVarsr-1;
+	  deltax=xr(k,j)-XRreorder(k,i);
+	  r(i,j)=std::exp(sum_neg_theta_dx_squared
+			  -correlations(k,0)*deltax*deltax);
+
+	}
+    }
+  } else if(corrFunc==EXP_CORR_FUNC) {
+    // ******************************************************************
+    // the exponential correlation function
+    // ******************************************************************
+    if(numVarsr==1) {
+      //special case for when there is only 1 input variable
+      double theta=correlations(0,0);
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i)
+	  r(i,j)=std::exp(-theta*std::fabs(xr(0,j)-XRreorder(0,i)));
+    }
+    else {
+      //general case there is more than 1 input variable
+      //even if nptsxr==1 outer looping once isn't a big performance hit
+      //so don't duplicate the code; smallest, i.e. k, loop is inside but
+      //that enables a single writing pass through the output array "r"
+      double sum_neg_theta_abs_dx;
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  sum_neg_theta_abs_dx=-correlations(0,0)* //=- is correct
+	    std::fabs(xr(0,j)-XRreorder(0,i));
+	  for(k=1; k<numVarsr-1; ++k)
+	    sum_neg_theta_abs_dx-=correlations(k,0)* //-= is correct
+	      std::fabs(xr(k,j)-XRreorder(k,i));
+	  k=numVarsr-1;
+	  r(i,j)=std::exp(sum_neg_theta_abs_dx
+			  -correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,i)));
+	}
+    }
+  } else if(corrFunc==POW_EXP_CORR_FUNC) {
+    // ******************************************************************
+    // the powered exponential correlation function 1<powExpCorrFuncPow<2
+    // because exponention and Gaussian (a.k.a. squared exponential) were
+    // pulled out
+    // ******************************************************************
+    if(numVarsr==1) {
+      //special case for when there is only 1 input variable
+      double theta=correlations(0,0);
+      for(i=0; i<numPointsKeep; ++i)
+	for(j=0; j<nptsxr; ++j)
+	  r(i,j)=std::exp(-theta*std::pow(std::fabs(xr(0,j)-XRreorder(0,i)),
+					  powExpCorrFuncPow));
+    } else {
+      //general case there is more than 1 input variable
+      //even if nptsxr==1 outer looping once isn't a big performance hit
+      //so don't duplicate the code; smallest, i.e. k, loop is inside but
+      //that enables a single writing pass through the output array "r"
+      double sum_neg_theta_abs_dx_pow;
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  sum_neg_theta_abs_dx_pow=-correlations(0,0)* //=- is correct
+	    std::pow(std::fabs(xr(0,j)-XRreorder(0,i)),powExpCorrFuncPow);
+	  for(k=1; k<numVarsr-1; ++k)
+	    sum_neg_theta_abs_dx_pow-=correlations(k,0)* //-= is correct
+	      std::pow(std::fabs(xr(k,j)-XRreorder(k,i)),powExpCorrFuncPow);
+	  k=numVarsr-1;
+	  r(i,j)=std::exp(sum_neg_theta_abs_dx_pow-correlations(k,0)*
+			  std::pow(std::fabs(xr(k,j)-XRreorder(k,i)),
+				   powExpCorrFuncPow));
+	}
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)) {
+    // ******************************************************************
+    // the Matern 3/2 Correlation function
+    // ******************************************************************
+    double theta_abs_dx;
+    if(numVarsr==1) {
+      //special case for when there is only 1 input variable
+      double theta=correlations(0,0);
+      for(i=0; i<numPointsKeep; ++i)
+	for(j=0; j<nptsxr; ++j) {
+	  theta_abs_dx=theta*std::fabs(xr(0,j)-XRreorder(0,i));
+	  r(i,j)=(1.0+theta_abs_dx)*std::exp(-theta_abs_dx);
+	}
+    } else {
+      //general case there is more than 1 input variable
+      //even if nptsxr==1 outer looping once isn't a big performance hit
+      //so don't duplicate the code; smallest, i.e. k, loop is inside but
+      //that enables a single writing pass through the output array "r"
+      double sum_neg_theta_abs_dx;
+      double matern_coef_prod;
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  theta_abs_dx=correlations(0,0)*std::fabs(xr(0,j)-XRreorder(0,i));
+	  matern_coef_prod=1.0+theta_abs_dx;
+	  sum_neg_theta_abs_dx=-theta_abs_dx; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,i));
+	    matern_coef_prod*=(1.0+theta_abs_dx);
+	    sum_neg_theta_abs_dx-=theta_abs_dx; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,i));
+	  r(i,j)=matern_coef_prod*(1.0+theta_abs_dx)*
+	    std::exp(sum_neg_theta_abs_dx-theta_abs_dx);
+	}
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)) {
+    // ******************************************************************
+    // the Matern 5/2 Correlation function
+    // ******************************************************************
+    double theta_abs_dx;
+    const double one_third=1.0/3.0;
+    if(numVarsr==1) {
+      //special case for when there is only 1 input variable
+      double theta=correlations(0,0);
+      for(i=0; i<numPointsKeep; ++i)
+	for(j=0; j<nptsxr; ++j) {
+	  theta_abs_dx=theta*std::fabs(xr(0,j)-XRreorder(0,i));
+	  r(i,j)=(1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third)*
+	    std::exp(-theta_abs_dx);
+	}
+    } else {
+      //general case there is more than 1 input variable
+      //even if nptsxr==1 outer looping once isn't a big performance hit
+      //so don't duplicate the code; smallest, i.e. k, loop is inside but
+      //that enables a single writing pass through the output array "r"
+      double sum_neg_theta_abs_dx;
+      double matern_coef_prod;
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  theta_abs_dx=correlations(0,0)*std::fabs(xr(0,j)-XRreorder(0,i));
+	  matern_coef_prod=1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third;
+	  sum_neg_theta_abs_dx=-theta_abs_dx; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,i));
+	    matern_coef_prod*=
+	      (1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third);
+	    sum_neg_theta_abs_dx-=theta_abs_dx; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,i));
+	  r(i,j)=matern_coef_prod*
+	    (1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third)*
+	    std::exp(sum_neg_theta_abs_dx-theta_abs_dx);
+	}
+    }
+  } else{
+      std::cerr << "unknown corrFunc in MtxDbl& eval_kriging_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const\n";
+      assert(false);
+  }
+
+  return r;
+}
+
+
+/** the inline function
+    MtxDbl& KrigingModel::correlation_matrix(MtxDbl& r, const MtxDbl& xr) const
+    calls either
+    MtxDbl& KrigingModel::eval_kriging_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const
+    OR
+    MtxDbl& KrigingModel::eval_gek_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const (i.e. this function)
+
+    r (lower case r) is the GEK correlation matrix between the
+    interpolation points and build data points, it used to EVALUATE but
+    not construct the emulator's Gaussian process error model
+    i.e. E(y(xr)|Y(XR))=g(xr)^T*betaHat+r^T*R^-1*eps where
+    eps=(Y-G(XR)^T*betaHat)
+    choices for correlation function are gaussian, and matern with
+    nu=1.5 or 2.5 KRD wrote this */
+MtxDbl& KrigingModel::eval_gek_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const
+{
+  if(buildDerOrder!=1) {
+    std::cerr << "You should only call eval_gek_correlation_matrix when you want to evaluate Gradient Enhanced Kriging\n";
+    assert(buildDerOrder==1);
+  }
+
+  int nptsxr=xr.getNCols(); //points at which we are evalutating the model
+#ifdef __KRIG_ERR_CHECK__
+  assert((xr.getNCols()==numVarsr)&&(0<nptsxr));
+#endif
+
+  r.newSize(numRowsR,nptsxr);
+  int i; //row index of the GEK r matrix 0<=i<numRowsR
+  int j; //column index of the GEK r matrix 0<=j<nptsxr also the xr point index
+  int k; //dimension index 0<=k<numVarsr (num real variables)
+  int ipt; //XRreorder point index
+  double deltax;  //xr(k,j)-XRreorder(k,ipt)
+  double krig_r;
+
+  //note to future developers on a point that may be confusing otherwise (you
+  //might otherwise mistake this for a bug) all of the derivatives in this
+  //file are with respect to XR not xr, the matern_1pt5_d1_mult_r and
+  //matern_2pt5_d1_mult_r functions in the .hpp file would be for derivatives
+  //with respect to xr (assuming deltax=xr-XR), the difference is here I've
+  //absorbed the negative into deltax going from -deltax (where deltax=XR-xr)
+  //to deltax=xr-XR;
+  int neqn_per_pt=numVarsr+1;
+
+  if(corrFunc==GAUSSIAN_CORR_FUNC) {
+    if(numVarsr==1) {
+      double theta=correlations(0,0); //save matrix access lookup
+      double two_theta = 2.0*theta;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=(xr(0,j)-XRreorder(0,ipt));
+	  krig_r=std::exp(-theta*deltax*deltax);
+	  r(i  ,j)=krig_r;
+	  r(i+1,j)=two_theta*deltax*krig_r; //this is a first
+	  //derivative with respect to XR not xr
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //since there's part of another point left and we know that
+	  //there is only one derivative it means that were missing that
+	  //derivative and only have the function value
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep)&&
+		 (i==numRowsR-1));
+#endif
+	  deltax=(xr(0,j)-XRreorder(0,ipt));
+	  r(i,j)=std::exp(-theta*deltax*deltax);
+	}
+      }
+    } else{ //there is more than 1 dimensions and more than one
+      //evaluation point
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(0,j)-XRreorder(0,ipt);
+	  r(i+1,j)=correlations(0,0)*deltax; //dr_dXR/(2*r)
+	  krig_r=-correlations(0,0)*deltax*deltax; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    deltax=xr(k,j)-XRreorder(k,ipt);
+	    r(i+1+k,j)=correlations(k,0)*deltax; //dr_dXR/(2*r)
+	    krig_r-=correlations(k,0)*deltax*deltax; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  deltax=xr(k,j)-XRreorder(k,ipt);
+	  krig_r=std::exp(krig_r-correlations(k,0)*deltax*deltax);
+	  r(i,j)=krig_r; //r(XR(i,:),xr(j,:)) (the correlation function)
+	  krig_r*=2.0; //now it's 2*kriging's correlation function to save
+	  //some ops
+	  //dr_dXR_k=2*theta(k)*(xr(k,j)-XRreorder(k,ipt))*r(xr(k,j),XRreorder(k,ipt))
+	  r(i+1+k,j)=correlations(k,0)*deltax*krig_r; //dr_dXR
+	  for(k=0; k<numVarsr-1; ++k)
+	    r(i+1+k,j)*=krig_r; //dr_dXR
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //the last XR point isn't a "whole point" we dropped some derivatives
+	  //out of its gradient to meet the bound on rcond, numExtraDerKeep
+	  //is the number of derivatives kept for the last point.  The
+	  //derivatives of the last point have NOT been reordered, they appear
+	  //in the same order as the input variables
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  //printf("deltax=xr(0,%d)-XRreorder(0,%d);\n",j,ipt);
+	  deltax=xr(0,j)-XRreorder(0,ipt);
+	  krig_r=-correlations(0,0)*deltax*deltax; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    deltax=xr(k,j)-XRreorder(k,ipt);
+	    krig_r-=correlations(k,0)*deltax*deltax; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  deltax=xr(k,j)-XRreorder(k,ipt);
+	  krig_r=std::exp(krig_r-correlations(k,0)*deltax*deltax);
+	  r(i,j)=krig_r; //r(XR(i,:),xr) (the correlation function)
+	  krig_r*=2.0; //now it's 2*kriging's correlation function to save
+	  //some ops
+	  //dr_dXR_k=2*theta(k)*(xr(k,j)-XRreorder(k,ipt))*r(xr(k,j),XRreorder(k,ipt))
+	  for(k=0; k<numExtraDerKeep; ++k)
+	    r(i+1+k,j)=correlations(k,0)*(xr(k,j)-XRreorder(k,ipt))*krig_r; //dr_dXR
+	}
+      }
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)) {
+    //this starts the section for the Matern 3/2 correlation function
+
+    double theta_abs_dx;
+    if(numVarsr==1) {
+      double theta=correlations(0,0); //save array access lookup
+      double theta_squared= theta*theta;
+      double exp_neg_theta_abs_dx;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=(xr(0,j)-XRreorder(0,ipt));
+	  theta_abs_dx=theta*std::fabs(deltax);
+	  exp_neg_theta_abs_dx=std::exp(-theta_abs_dx);
+	  r(i  ,j)=(1.0+theta_abs_dx)*exp_neg_theta_abs_dx; //1D correlation
+	  //function
+	  r(i+1,j)=theta_squared*deltax*exp_neg_theta_abs_dx; //this is a first
+	  //derivative with respect to XR not xr
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //since there's part of another point left and we know that
+	  //there is only one derivative it means that were missing that
+	  //derivative and only have the function value
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep)&&
+		 (i==numRowsR-1));
+#endif
+	  theta_abs_dx=theta*std::fabs(xr(0,j)-XRreorder(0,ipt));
+	  r(i,j)=(1.0+theta_abs_dx)*std::exp(-theta_abs_dx); //1D correlation
+	  //function
+	}
+      }
+    }
+    else{ //there is more than 1 dimension
+      double matern_coef, matern_coef_prod, sum_neg_theta_abs_dx;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(0,j)-XRreorder(0,ipt);
+	  theta_abs_dx=correlations(0,0)*std::fabs(deltax);
+	  matern_coef=1.0+theta_abs_dx;
+	  matern_coef_prod=matern_coef;
+	  r(i+1,j)= //dr_dXR/r
+	    correlations(0,0)*correlations(0,0)*deltax/matern_coef;
+	  sum_neg_theta_abs_dx=-theta_abs_dx; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    deltax=xr(k,j)-XRreorder(k,ipt);
+	    theta_abs_dx=correlations(k,0)*std::fabs(deltax);
+	    matern_coef=1.0+theta_abs_dx;
+	    matern_coef_prod*=matern_coef;
+	    r(i+1+k,j)= //dr_dXR/r
+	      correlations(k,0)*correlations(k,0)*deltax/matern_coef;
+	    sum_neg_theta_abs_dx-=theta_abs_dx; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  deltax=xr(k,j)-XRreorder(k,ipt);
+	  theta_abs_dx=correlations(k,0)*std::fabs(deltax);
+	  matern_coef=1.0+theta_abs_dx;
+	  krig_r=matern_coef_prod*matern_coef*
+	    std::exp(sum_neg_theta_abs_dx-theta_abs_dx);
+	  r(i,j)=krig_r; //r(XR(i,:),xr) (the correlation function)
+	  r(i+1+k,j)= //dr_dXR
+	    correlations(k,0)*correlations(k,0)*deltax/matern_coef*krig_r;
+	  for(k=0; k<numVarsr-1; ++k)
+	    r(i+1+k,j)*=krig_r; //dr_dXR
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //the last XR point isn't a "whole point" we dropped some derivatives
+	  //out of its gradient to meet the bound on rcond, numExtraDerKeep
+	  //is the number of derivatives kept for the last point.  The
+	  //derivatives of the last point have NOT been reordered, they appear
+	  //in the same order as the input variables
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  theta_abs_dx=correlations(0,0)*std::fabs(xr(0,j)-XRreorder(0,ipt));
+	  matern_coef_prod=1.0+theta_abs_dx;
+	  sum_neg_theta_abs_dx=-theta_abs_dx; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,ipt));
+	    matern_coef_prod*=(1.0+theta_abs_dx);
+	    sum_neg_theta_abs_dx-=theta_abs_dx; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,ipt));
+	  krig_r=matern_coef_prod*(1.0+theta_abs_dx)*
+	    std::exp(sum_neg_theta_abs_dx-theta_abs_dx);
+	  r(i,j)=krig_r; //r(XR(i,:),xr) (the correlation function)
+	  for(k=0; k<numExtraDerKeep; ++k) {
+	    deltax=xr(k,j)-XRreorder(k,ipt);
+	    r(i+1+k,j)=krig_r * //r(i+1+k,j)=dr_dXR
+	      correlations(k,0)*correlations(k,0)*deltax/
+	      (1.0+correlations(k,0)*std::fabs(deltax));
+	  }
+	}
+      }
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)) {
+    //this starts the section for the Matern 5/2 correlation function
+
+    const double one_third=1.0/3.0;
+    double theta_abs_dx;
+    if(numVarsr==1) {
+      double theta=correlations(0,0); //save array access lookup
+      double theta_squared= theta*theta;
+      double exp_neg_theta_abs_dx;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=(xr(0,j)-XRreorder(0,ipt));
+	  theta_abs_dx=theta*std::fabs(deltax);
+	  exp_neg_theta_abs_dx=std::exp(-theta_abs_dx);
+	  r(i  ,j)=(1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third)*
+	    exp_neg_theta_abs_dx; //1D correlation function
+	  r(i+1,j)=theta_squared*deltax*(1.0+theta_abs_dx)*one_third*
+	    exp_neg_theta_abs_dx; //this is a first derivative with respect
+	  //to XR not xr
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //since there's part of another point left and we know that
+	  //there is only one derivative it means that were missing that
+	  //derivative and only have the function value
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep)&&
+		 (i==numRowsR-1));
+#endif
+	  theta_abs_dx=theta*std::fabs(xr(0,j)-XRreorder(0,ipt));
+	  r(i  ,j)=(1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third)*
+	    std::exp(-theta_abs_dx); //1D correlation function
+	}
+      }
+    }
+    else{ //there is more than 1 dimension
+      double matern_coef, matern_coef_prod, sum_neg_theta_abs_dx;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(0,j)-XRreorder(0,ipt);
+	  theta_abs_dx=correlations(0,0)*std::fabs(deltax);
+	  matern_coef=1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third;
+	  matern_coef_prod=matern_coef;
+	  r(i+1,j)= //dr_dXR/r
+	    correlations(0,0)*correlations(0,0)*deltax*(1.0+theta_abs_dx)*
+	    one_third/matern_coef;
+	  sum_neg_theta_abs_dx=-theta_abs_dx; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    deltax=xr(k,j)-XRreorder(k,ipt);
+	    theta_abs_dx=correlations(k,0)*std::fabs(deltax);
+	    matern_coef=1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third;
+	    matern_coef_prod*=matern_coef;
+	    r(i+1+k,j)= //dr_dXR/r
+	      correlations(k,0)*correlations(k,0)*deltax*(1.0+theta_abs_dx)*
+	      one_third/matern_coef;
+	    sum_neg_theta_abs_dx-=theta_abs_dx; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  deltax=xr(k,j)-XRreorder(k,ipt);
+	  theta_abs_dx=correlations(k,0)*std::fabs(deltax);
+	  matern_coef=1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third;
+	  krig_r=matern_coef_prod*matern_coef*
+	    std::exp(sum_neg_theta_abs_dx-theta_abs_dx);
+	  r(i,j)=krig_r; //r(XR(i,:),xr) (the correlation function)
+	  r(i+1+k,j)= //dr_dXR
+	    correlations(k,0)*correlations(k,0)*deltax*(1.0+theta_abs_dx)*
+	    one_third/matern_coef*krig_r;
+	  for(k=0; k<numVarsr-1; ++k)
+	    r(i+1+k,j)*=krig_r; //dr_dXR
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //the last XR point isn't a "whole point" we dropped some derivatives
+	  //out of its gradient to meet the bound on rcond, numExtraDerKeep
+	  //is the number of derivatives kept for the last point.  The
+	  //derivatives of the last point have NOT been reordered, they appear
+	  //in the same order as the input variables
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  theta_abs_dx=correlations(0,0)*std::fabs(xr(0,j)-XRreorder(0,ipt));
+	  matern_coef_prod=1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third;
+	  sum_neg_theta_abs_dx=-theta_abs_dx; //=- is correct
+	  for(k=1; k<numVarsr-1; ++k) {
+	    theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,ipt));
+	    matern_coef_prod*=
+	      (1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third);
+	    sum_neg_theta_abs_dx-=theta_abs_dx; //-= is correct
+	  }
+	  k=numVarsr-1;
+	  theta_abs_dx=correlations(k,0)*std::fabs(xr(k,j)-XRreorder(k,ipt));
+	  krig_r=matern_coef_prod*
+	    (1.0+theta_abs_dx+theta_abs_dx*theta_abs_dx*one_third)*
+	    std::exp(sum_neg_theta_abs_dx-theta_abs_dx);
+	  r(i,j)=krig_r; //r(XR(i,:),xr) (the correlation function)
+	  for(k=0; k<numExtraDerKeep; ++k) {
+	    deltax=xr(k,j)-XRreorder(k,ipt);
+	    theta_abs_dx=correlations(k,0)*std::fabs(deltax);
+	    r(i+1+k,j)=krig_r * //r(i+1+k,j)=dr_dXR
+	      correlations(k,0)*correlations(k,0)*deltax*(1.0+theta_abs_dx)/
+	      (3.0*(1.0+theta_abs_dx)+theta_abs_dx*theta_abs_dx);
+
+	  }
+	}
+      }
+    }
+  } else{
+    std::cerr << "Unknown or Invalid Correlation function for Gradient Enhanced Kriging in MtxDbl& KrigingModel::eval_gek_correlation_matrix(MtxDbl& r, const MtxDbl& xr) const\n";
+    assert(false);
+  }
+
+
+  return r;
+}
+
+
+///Ider is the variable/dimension not the point
+MtxDbl& KrigingModel::eval_kriging_dcorrelation_matrix_dxI(MtxDbl& dr, const MtxDbl& r, const MtxDbl& xr, int Ider) const
+{
+  if(buildDerOrder!=0) {
+    std::cerr << "You should only call eval_kriging_dcorrelation_matrix_dxI when you want to evaluate regular Kriging's (not GEK's) first derivative.\n";
+    assert(buildDerOrder==0);
+  }
+  int nptsxr=xr.getNCols();
+#ifdef __KRIG_ERR_CHECK__
+  assert((r.getNCols()==nptsxr)&&(r.getNRows()==numRowsR)&&
+	 (xr.getNRows()==numVarsr)&&(0<=Ider)&&(Ider<numVarsr));
+#endif
+  dr.newSize(numRowsR,nptsxr);
+  int i; //row index of r & dr, also the point index of reordered XR
+  int j; //column index of r & dr, also the point index of xr
+
+  if(corrFunc==GAUSSIAN_CORR_FUNC) {
+    // *******************************************************************
+    // Gaussian Correlation Function
+    // GAUSSIAN_CORR_FUNC is infinitely differentiable
+    // *******************************************************************
+    double neg_two_theta=-2.0*correlations(Ider,0); //save matrix dereference
+    //for speed
+    for(j=0; j<nptsxr; ++j)
+      for(i=0; i<numPointsKeep; ++i)
+	dr(i,j)=r(i,j)*neg_two_theta*(xr(Ider,j)-XRreorder(Ider,i));
+  } else if(corrFunc==EXP_CORR_FUNC) {
+    // *******************************************************************
+    // Exponential Correlation Function
+    // 1D EXP_CORR_FUNC r(x1,x2) is differentiable except where x1==x2
+    // this is correct for x1!=x2
+    // *******************************************************************
+    double neg_theta=-correlations(Ider,0); //save matrix dereference for
+    //speed
+    for(j=0; j<nptsxr; ++j)
+      for(i=0; i<numPointsKeep; ++i)
+	dr(i,j)=r(i,j)*neg_theta*dsign(xr(Ider,j)-XRreorder(Ider,i));
+  } else if(corrFunc==POW_EXP_CORR_FUNC) {
+    // *******************************************************************
+    // Powered Exponential Correlation Function with 1<power<2
+    // 1D POW_EXP_CORR_FUNC r(x1,x2) is once differential everywhere (and
+    // twice+ differentiable where x1!=x2)
+    // *******************************************************************
+    double neg_theta_pow=-powExpCorrFuncPow*correlations(Ider,0); //save
+    //matrix dereference for speed
+    double pow_m_1=powExpCorrFuncPow-1.0; //for speed
+    double delta_x;
+    for(int j=0; j<nptsxr; ++j)
+      for(int i=0; i<numPointsKeep; ++i) {
+	delta_x=xr(Ider,j)-XRreorder(Ider,i);
+	dr(i,j)=r(i,j)*dsign(delta_x)*neg_theta_pow*
+	  std::pow(std::fabs(delta_x),pow_m_1);
+      }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)) {
+    // *******************************************************************
+    // Matern 3/2 Correlation Function
+    // 1D MATERN_CORR_FUNC 1.5 is once differentiable everywhere (and
+    // twice+ differentiable where x1!=x2, while not twice differentiable
+    // at x1==x2 the limit of the 2nd derivative is defined and is the
+    // same from both sides see Lockwood and Anitescu)
+    // *******************************************************************
+    double theta=correlations(Ider,0); //save matrix dereference for speed
+    for(j=0; j<nptsxr; ++j)
+      for(i=0; i<numPointsKeep; ++i)
+	dr(i,j)=r(i,j)*
+	  matern_1pt5_d1_mult_r(theta,xr(Ider,j)-XRreorder(Ider,i));
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)) {
+    // *******************************************************************
+    // Matern 5/2 Correlation Function
+    // 1D MATERN_CORR_FUNC 2.5 is twice differentiable everywhere (and
+    // twice+ differentiable where x1!=x2)
+    // *******************************************************************
+    double theta=correlations(Ider,0); //save matrix dereference for speed
+    for(j=0; j<nptsxr; ++j)
+      for(i=0; i<numPointsKeep; ++i)
+	dr(i,j)=r(i,j)*
+	  matern_2pt5_d1_mult_r(theta,xr(Ider,j)-XRreorder(Ider,i));
+  } else{
+    std::cerr << "unknown corrFunc in MtxDbl& KrigingModel::eval_kriging_dcorrelation_matrix_dxI(MtxDbl& dr, const MtxDbl& r, const MtxDbl& xr, int Ider) const\n";
+    assert(false);
+  }
+  return dr;
+}
+///Ider is the variable/dimension not the point
+MtxDbl& KrigingModel::eval_gek_dcorrelation_matrix_dxI(MtxDbl& dr, const MtxDbl& r, const MtxDbl& xr, int Ider) const
+{
+  if(buildDerOrder!=1) {
+    std::cerr << "You should only call eval_gek_dcorrelation_matrix_dxI when you want to evaluate Gradient Enhanced Kriging's first derivative\n";
+    assert(buildDerOrder==1);
+  }
+  int nptsxr=xr.getNCols();
+#ifdef __KRIG_ERR_CHECK__
+  assert((r.getNCols()==nptsxr)&&(r.getNRows()==numRowsR)&&
+	 (xr.getNRows()==numVarsr)&&(0<=Ider)&&(Ider<numVarsr));
+#endif
+  dr.newSize(numRowsR,nptsxr);
+  int neqn_per_pt=1+numVarsr;
+  int i; //row index of r & dr
+  int j; //column index of r & dr, also the point index of xr
+  int k; //dimension index
+  int ipt; //point index of reordered XR
+
+  if(corrFunc==GAUSSIAN_CORR_FUNC) {
+    // *******************************************************************
+    // Gaussian Correlation Function
+    // GAUSSIAN_CORR_FUNC is infinitely differentiable
+    // *******************************************************************
+    double two_theta=2.0*correlations(Ider,0); //save matrix dereference for speed
+    double neg_two_theta_dx;
+    if(numVarsr==1)
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  neg_two_theta_dx=two_theta*(XRreorder(Ider,ipt)-xr(Ider,j));
+	  dr(i  ,j)=r(i,j)*neg_two_theta_dx;
+	  dr(i+1,j)=r(i,j)*two_theta + r(i+1,j)*neg_two_theta_dx;
+	}
+	// since there is only one dimension if there is a partial point
+	// it will be a function value only, and actually recalculating it
+	// will likely be faster on average then checking if there's a
+	// partial point and calculating it if needed
+	ipt=numPointsKeep-1;
+	i=ipt*2;
+	dr(i  ,j)=r(i,j)*two_theta*(XRreorder(Ider,ipt)-xr(Ider,j));
+      }
+    else{
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  neg_two_theta_dx=two_theta*(XRreorder(Ider,ipt)-xr(Ider,j));
+	  dr(i,j)=r(i,j)*neg_two_theta_dx;
+	  for(k=0; k<numVarsr; ++k)
+	    dr(i+1+k,j)=r(i+1+k,j)*neg_two_theta_dx;
+	  dr(i+1+Ider,j)+=r(i,j)*two_theta;
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should be what we need them to be
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  neg_two_theta_dx=two_theta*(XRreorder(Ider,ipt)-xr(Ider,j));
+	  dr(i,j)=r(i,j)*neg_two_theta_dx;
+	  for(k=0; k<numExtraDerKeep; ++k)
+	    dr(i+1+k,j)=r(i+1+k,j)*neg_two_theta_dx;
+	  if(Ider<numExtraDerKeep)
+	    dr(i+1+Ider,j)+=r(i,j)*two_theta;
+	}
+      }
+    }
+  } else if(corrFunc==EXP_CORR_FUNC) {
+    std::cerr << "The exponential correlation function is not a valid correlation function for gradient enhanced Kriging\n";
+      assert(false);
+  } else if(corrFunc==POW_EXP_CORR_FUNC) {
+    std::cerr << "The powered exponential (with power < 2) correlation function is not a valid correlation function for gradient enhanced Kriging\n";
+      assert(false);
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)) {
+    // *******************************************************************
+    // Matern 3/2 Correlation Function
+    // 1D MATERN_CORR_FUNC 1.5 is once differentiable everywhere (and
+    // twice+ differentiable where x1!=x2, while not twice differentiable
+    // at x1==x2 the limit of the 2nd derivative is defined and is the
+    // same from both sides see Lockwood and Anitescu)
+    // *******************************************************************
+    double theta=correlations(Ider,0); //save matrix dereference for speed
+    double neg_theta_squared=-theta*theta;
+    double deltax;
+    double matern_coef;
+    if(numVarsr==1)
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=(xr(Ider,j)-XRreorder(Ider,ipt));
+	  matern_coef=1.0+theta*std::fabs(deltax);
+	  dr(i  ,j)=r(i,j)*neg_theta_squared*deltax/matern_coef;
+	  dr(i+1,j)=r(i,j)*neg_theta_squared*(1.0-2.0/matern_coef);
+	}
+	// since there is only one dimension if there is a partial point
+	// it will be a function value only, and actually recalculating it
+	// will likely be faster on average then checking if there's a
+	// partial point and calculating it if needed
+	ipt=numPointsKeep-1;
+	i=ipt*2;
+	deltax=(xr(Ider,j)-XRreorder(Ider,ipt));
+	dr(i,j)=r(i,j)*neg_theta_squared*deltax/(1.0+theta*std::fabs(deltax));
+      }
+    else{
+      double matern_d1_mult_r;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=(xr(Ider,j)-XRreorder(Ider,ipt));
+	  matern_coef=1.0+theta*std::fabs(deltax);
+	  matern_d1_mult_r=neg_theta_squared*deltax/matern_coef;
+	  dr(i  ,j)=r(i,j)*matern_d1_mult_r;
+	  for(k=0; k<numVarsr; ++k)
+	    dr(i+1+k,j)=r(i+1+k,j)*matern_d1_mult_r;
+	  dr(i+1+Ider,j)=r(i,j)*neg_theta_squared*(1.0-2.0/matern_coef);
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should be what we need them to be
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=(xr(Ider,j)-XRreorder(Ider,ipt));
+	  matern_coef=1.0+theta*std::fabs(deltax);
+	  matern_d1_mult_r=neg_theta_squared*deltax/matern_coef;
+	  dr(i  ,j)=r(i,j)*matern_d1_mult_r;
+	  for(k=0; k<numExtraDerKeep; ++k)
+	    dr(i+1+k,j)=r(i+1+k,j)*matern_d1_mult_r;
+	  if(Ider<numExtraDerKeep)
+	    dr(i+1+Ider,j)=r(i,j)*neg_theta_squared*(1.0-2.0/matern_coef);
+	}
+      }
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)) {
+    // *******************************************************************
+    // Matern 5/2 Correlation Function
+    // 1D MATERN_CORR_FUNC 2.5 is twice differentiable everywhere (and
+    // twice+ differentiable where x1!=x2)
+    // *******************************************************************
+    double theta=correlations(Ider,0); //save matrix dereference for speed
+    double theta_squared=theta*theta;
+    double theta_abs_dx;
+    double deltax;
+    if(numVarsr==1) {
+      double r_theta_squared_div_3_matern_coef;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=(xr(Ider,j)-XRreorder(Ider,ipt));
+	  theta_abs_dx=theta*std::fabs(deltax);
+	  r_theta_squared_div_3_matern_coef=r(i,j)*theta_squared/
+	    (3.0*(1.0+theta_abs_dx)+theta_abs_dx*theta_abs_dx);
+	  dr(i  ,j)=-r_theta_squared_div_3_matern_coef*
+	    deltax*(1.0+theta_abs_dx);
+	  dr(i+1,j)=r_theta_squared_div_3_matern_coef*
+	    (1.0+theta_abs_dx-theta_abs_dx*theta_abs_dx);
+	}
+	// since there is only one dimension if there is a partial point
+	// it will be a function value only, and actually recalculating it
+	// will likely be faster on average then checking if there's a
+	// partial point and calculating it if needed
+	ipt=numPointsKeep-1;
+	i=ipt*2;
+	deltax=(xr(Ider,j)-XRreorder(Ider,ipt));
+	theta_abs_dx=theta*std::fabs(deltax);
+	dr(i,j)=-r(i,j)*theta_squared/
+	  (3.0*(1.0+theta_abs_dx)+theta_abs_dx*theta_abs_dx)*
+	  deltax*(1.0+theta_abs_dx);
+      }
+    } else{
+      double theta_squared_div_3_matern_coef;
+      double matern_d1_mult_r;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(Ider,j)-XRreorder(Ider,ipt);
+	  theta_abs_dx=theta*std::fabs(deltax);
+	  theta_squared_div_3_matern_coef=theta_squared/
+	    (3.0*(1.0+theta_abs_dx)+theta_abs_dx*theta_abs_dx);
+	  matern_d1_mult_r=-theta_squared_div_3_matern_coef*
+	    deltax*(1.0+theta_abs_dx);
+	  dr(i  ,j)=r(i,j)*matern_d1_mult_r;
+	  for(k=0; k<numVarsr; ++k)
+	    dr(i+1+k,j)=r(i+1+k,j)*matern_d1_mult_r;
+	  dr(i+1+Ider,j)=r(i,j)*theta_squared_div_3_matern_coef*
+	    (1.0+theta_abs_dx-theta_abs_dx*theta_abs_dx);
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should be what we need them to be
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=xr(Ider,j)-XRreorder(Ider,ipt);
+	  theta_abs_dx=theta*std::fabs(deltax);
+	  theta_squared_div_3_matern_coef=theta_squared/
+	    (3.0*(1.0+theta_abs_dx)+theta_abs_dx*theta_abs_dx);
+	  matern_d1_mult_r=-theta_squared_div_3_matern_coef*
+	    deltax*(1.0+theta_abs_dx);
+	  dr(i  ,j)=r(i,j)*matern_d1_mult_r;
+	  for(k=0; k<numExtraDerKeep; ++k)
+	    dr(i+1+k,j)=r(i+1+k,j)*matern_d1_mult_r;
+	  if(Ider<numExtraDerKeep)
+	    dr(i+1+Ider,j)=r(i,j)*theta_squared_div_3_matern_coef*
+	      (1.0+theta_abs_dx-theta_abs_dx*theta_abs_dx);
+	}
+      }
+    }
+  } else{
+    std::cerr << "unknown corrFunc in MtxDbl& KrigingModel::eval_gek_dcorrelation_matrix_dxI(MtxDbl& dr, const MtxDbl& r, const MtxDbl& xr, int Ider) const\n";
+    assert(false);
+  }
+
+  return dr;
+}
+
+
+
+MtxDbl& KrigingModel::eval_kriging_d2correlation_matrix_dxIdxJ(MtxDbl& d2r, const MtxDbl& drI, const MtxDbl& r, const MtxDbl& xr, int Ider, int Jder) const
+{
+  if(buildDerOrder!=0) {
+    std::cerr << "You should only call eval_kriging_correlation_matrix when you want to evaluate regular Kriging (not GEK)\n";
+    assert(buildDerOrder==0);
+  }
+
+  int nptsxr=xr.getNCols(); //points at which we are evalutating the model
+  d2r.newSize(numPointsKeep,nptsxr);
+
+#ifdef __KRIG_ERR_CHECK__
+  assert((r.getNCols()==nptsxr)&&(r.getNRows()==numPointsKeep)&&
+	 (xr.getNRows()==numVarsr)&&(0<=Jder)&&(Jder<numVarsr));
+#endif
+
+  int i; //row index of r, d1r, & d2r; also the point index of reordered XR
+  int j; //column index of r, d1r, & d2r; also the point index of xr
+
+  if(corrFunc==GAUSSIAN_CORR_FUNC) {
+    // *********************************************************************
+    // The GAUSSIAN CORRELATION FUNCTION
+    // is infinitely differentiable, i.e. is C^infinity continuous
+    // *********************************************************************
+    double neg_two_theta_J=-2.0*correlations(Jder,0);
+    if(Ider==Jder) {
+      // taking the 2nd derivative of the 1D correlation function
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i)
+	  d2r(i,j)=neg_two_theta_J*
+	    ((xr(Jder,j)-XRreorder(Jder,i))*drI(i,j)+r(i,j));
+    } else {
+      // taking the product of the 1st derivative of 2 independent 1D
+      // correlation functions
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i)
+	  d2r(i,j)=neg_two_theta_J*
+	    (xr(Jder,j)-XRreorder(Jder,i))*drI(i,j);
+    }
+  } else if(corrFunc==EXP_CORR_FUNC) {
+    // *********************************************************************
+    // The EXPONENTIAL CORRELATION FUNCTION
+    // the first derivative WRT theta(J) is
+    //     drJ=-theta(J)*sign(xr(J)-XR(J))*r
+    // if away from xr(J)==XR(J) then d(sign(xr(J)-XR(J))/dxr(J)=0
+    // it at xr(J)==XR(J) then derivative of sign (a.k.a step function) is
+    // two times the delta function (or a rectangle with area 2, whose base
+    // width is a point, i.e. zero, meaning the delta function is infinite).
+    // The following is correct as long as xr(J)=/=XR(J), i.e. as long as
+    // the evaluation point doesn't share a coordinate with any build point.
+    // *********************************************************************
+    double neg_theta_J=-correlations(Jder,0);
+    for(j=0; j<nptsxr; ++j)
+      for(i=0; i<numPointsKeep; ++i)
+	d2r(i,j)=neg_theta_J*dsign(xr(Jder,j)-XRreorder(Jder,i))*drI(i,j);
+  } else if(corrFunc==POW_EXP_CORR_FUNC) {
+    // *********************************************************************
+    // The POWERED EXPONENTIAL CORRELATION FUNCTION with 1<power<2
+    //
+    // the 1st derivative with respect to xr of the 1D correlation function
+    // is defined
+    //
+    // The 2nd derivative with respect to xr of the 1D correlation function
+    // *is undefined at xr==XR,
+    // *approaches negative infinity as xr approaches XR from below, and
+    // *approaches positive infinity as xr approaches XR from above
+    // when xr==XR we use the average of the second derivative from above and
+    // the second derivative from below, that average is exactly zero
+    // *********************************************************************
+    double neg_thetaJ_pow=-correlations(Jder,0)*powExpCorrFuncPow;
+    double pow_minus_1=powExpCorrFuncPow-1.0;
+    double abs_dx;
+    double deltax;
+    if(Ider==Jder) {
+      // taking the 2nd derivative of the 1D correlation function
+      double pow_minus_2=powExpCorrFuncPow-2.0;
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,i);
+	  if(deltax==0) {
+	    d2r(i,j)=0.0;
+	    std::cerr << "the 2nd derivative of the powered exponential correlation function (with 1<power<2) is undefined when a coordinate of the evaluation point equals the coordinate of a build point, using the zero as the average of + infinity (from above) and - infinity (from below)\n";
+	  }
+	  else{
+	    abs_dx=std::fabs(deltax);
+	    d2r(i,j)=neg_thetaJ_pow*dsign(deltax)*
+	      (pow_minus_1*std::pow(abs_dx,pow_minus_2)*r(i,j)+
+	       std::pow(abs_dx,pow_minus_1)*drI(i,j));
+	  }
+	}
+    } else {
+      //we are taking the product of the first derivatives of 2 independent
+      //1D correlation functions so we don't have to worry about the 2nd
+      //derivative of a 1D correlation function being undefined
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,i);
+	  d2r(i,j)=neg_thetaJ_pow*dsign(deltax)*
+	    std::pow(std::fabs(deltax),pow_minus_1)*drI(i,j);
+	}
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)) {
+    // *********************************************************************
+    // The MATERN 3/2 CORRELATION FUNCTION
+    //
+    // the 1st derivative with respect to xr of the 1D correlation function
+    // is defined
+    //
+    // The 2nd derivative with respect to xr of the 1D correlation function
+    // *is undefined at xr==XR,
+    // *is -theta^2*(1-theta*|xr-XR|)*exp(-theta*|xr-XR|) at xr=/=XR
+    // *approaches -theta^2 from above and below
+    // when xr==XR we use the limit, -theta^2
+    // this follows the approach of
+    //   Lockwood, Brian A. and Anitescu, Mihai, "Gradient-Enhanced
+    //      Universal Kriging for Uncertainty Proagation"
+    //      Preprint ANL/MCS-P1808-1110
+    // *********************************************************************
+    double thetaJ=correlations(Jder,0);
+    double neg_thetaJ_squared=-thetaJ*thetaJ;
+    double deltax;
+    if(Ider==Jder) {
+      // taking the 2nd derivative of the 1D correlation function
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,i);
+	  d2r(i,j)=neg_thetaJ_squared*
+	    (2.0/(1.0+thetaJ*std::fabs(deltax))-1.0)*r(i,j);
+	}
+    }else{
+      // taking the product of the 1st derivative of 2 independent 1D
+      // correlation functions
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,i);
+	  d2r(i,j)=neg_thetaJ_squared*deltax/(1.0+thetaJ*std::fabs(deltax))*
+	    drI(i,j);
+	}
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)) {
+    // *********************************************************************
+    // The MATERN 5/2 CORRELATION FUNCTION
+    //
+    // the 1st and 2nd derivatives with respect to xr of the 1D correlation
+    // function are defined, no special treatment is required
+    // *********************************************************************
+    double thetaJ=correlations(Jder,0);
+    double neg_thetaJ_squared=-thetaJ*thetaJ;
+    double deltax;
+    double thetaJ_abs_dx;
+    if(Ider==Jder) {
+      // taking the 2nd derivative of the 1D correlation function
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,i);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  d2r(i,j)=neg_thetaJ_squared*
+	    (1.0+thetaJ_abs_dx-thetaJ_abs_dx*thetaJ_abs_dx)/
+	    (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx)*
+	    r(i,j);
+	}
+    }
+    else {
+      // taking the product of the 1st derivative of 2 independent 1D
+      // correlation functions
+      for(j=0; j<nptsxr; ++j)
+	for(i=0; i<numPointsKeep; ++i) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,i);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  d2r(i,j)=neg_thetaJ_squared*deltax*(1.0+thetaJ_abs_dx)/
+	    (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx)*
+	    drI(i,j);
+	}
+    }
+  } else{
+    std::cerr << "unknown corrFunc in MtxDbl& KrigingModel::eval_kriging_d2correlation_matrix_dxIdxJ(MtxDbl& d2r, const MtxDbl& drI, const MtxDbl& r, const MtxDbl& xr, int Ider, int Jder) const\n";
+    assert(false);
+  }
+  return d2r;
+}
+MtxDbl& KrigingModel::eval_gek_d2correlation_matrix_dxIdxJ(MtxDbl& d2r, const MtxDbl& drI, const MtxDbl& r, const MtxDbl& xr, int Ider, int Jder) const
+{
+  if(buildDerOrder!=1) {
+    std::cerr << "You should only call eval_gek_dcorrelation_matrix_dxI when you want to evaluate Gradient Enhanced Kriging's second derivative\n";
+    assert(buildDerOrder==1);
+  }
+  int nptsxr=xr.getNCols(); //points at which we are evalutating the model
+  d2r.newSize(numRowsR,nptsxr);
+
+#ifdef __KRIG_ERR_CHECK__
+  assert((r.getNCols()==nptsxr)&&(r.getNRows()==numPointsKeep)&&
+	 (xr.getNRows()==numVarsr)&&(0<=Jder)&&(Jder<numVarsr));
+#endif
+
+  int i; //row index of r, d1r, & d2r
+  int j; //column index of r, d1r, & d2r; also the point index of xr
+  int k; //dimension index
+  int ipt; //point index of reordered XR
+  int neqn_per_pt=numVarsr+1;
+  double deltax;
+
+  if(corrFunc==GAUSSIAN_CORR_FUNC) {
+    // *********************************************************************
+    // The GAUSSIAN CORRELATION FUNCTION
+    // is infinitely differentiable, i.e. is C^infinity continuous
+    // the reuse lower order derivates formulas are derived by taking
+    // derivatives in the reverse order of occurance and not expanding
+    // derivatives or r of d1r (here called drI)
+    // *********************************************************************
+    double neg_two_thetaJ=-2.0*correlations(Jder,0);
+    if(numVarsr==1) {
+      // if there is only one input variable we are taking the 2nd derivative
+      // of the 1D correlation function
+      // AND WE KNOW THAT Ider=Jder=k so we don't have to "if" to add the
+      // the extra terms
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  d2r(i  ,j)=neg_two_thetaJ*(deltax*drI(i  ,j)+r(i  ,j));
+	  d2r(i+1,j)=neg_two_thetaJ*(deltax*drI(i+1,j)+r(i+1,j)-drI(i,j));
+	}
+	// since there is only one dimension if there is a partial point
+	// it will be a function value only, and actually recalculating it
+	// will likely be faster on average then checking if there's a
+	// partial point and calculating it if needed
+	ipt=numPointsKeep-1;
+	i=ipt*2;
+	d2r(i,j)=neg_two_thetaJ*
+	  ((xr(Jder,j)-XRreorder(Jder,ipt))*drI(i,j)+r(i,j));
+      }
+    } else if(Ider==Jder) {
+      // taking the 2nd derivative of the 1D correlation function
+      // the extra term is -2*theta(J)*r (remember r is for GEK so
+      // the k loop part of it contains derivatives of the Kriging
+      // correlation function with respect to XR)
+      //      std::cout << "size(r)=[" << r.getNRows() << "," << r.getNCols() << "]\n"
+      //		<< "size(drI)=[" << drI.getNRows() << "," << drI.getNCols() << "\n"
+      //	<< "size(d2r)=[" << d2r.getNRows() << "," << d2r.getNCols()
+      //	<< std::endl;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  d2r(i,j)=neg_two_thetaJ*(deltax*drI(i,j)+r(i,j));
+	  for(k=0; k<numVarsr; ++k) {
+	    //std::cout << "i=" << i << " j=" << j << " k=" << k << std::endl;
+	    d2r(i+1+k,j)=neg_two_thetaJ*(deltax*drI(i+1+k,j)+r(i+1+k,j));
+	  }
+	  d2r(i+1+Jder,j)-=neg_two_thetaJ*drI(i,j); //minus a negative is
+	  //a positive is correct, this extra term is for Jder=k
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should already have the values we need them to
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  d2r(i,j)=neg_two_thetaJ*(deltax*drI(i,j)+r(i,j));
+	  for(k=0; k<numExtraDerKeep; ++k)
+	    d2r(i+1+k,j)=neg_two_thetaJ*(deltax*drI(i+1+k,j)+r(i+1+k,j));
+	  if(Jder<numExtraDerKeep)
+	    d2r(i+1+Jder,j)-=neg_two_thetaJ*drI(i,j); //minus a negative is
+  	    //a positive is correct, this extra term is for Jder=k
+	}
+      }
+    } else {
+      // taking the product of the 1st derivative of 2 independent 1D
+      // correlation functions, (actually because this is for GEK, the
+      // k loop is 2nd derivative of the Kriging r, in dimensions
+      // independent of the one we're now taking the 1st derivative of)
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  d2r(i,j)=neg_two_thetaJ*deltax*drI(i,j);
+	  for(k=0; k<numVarsr; ++k)
+	    d2r(i+1+k,j)=neg_two_thetaJ*deltax*drI(i+1+k,j);
+	  d2r(i+1+Jder,j)-=neg_two_thetaJ*drI(i,j); //actually one element
+	  //of the k loop is the dimension we're taking a derivative with
+	  //respect to, it gets an extra term added to it. minus a negative
+	  //is a positive is correct, this extra term is for Jder=k
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should already have the values we need them to
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  d2r(i,j)=neg_two_thetaJ*deltax*drI(i,j);
+	  for(k=0; k<numExtraDerKeep; ++k)
+	    d2r(i+1+k,j)=neg_two_thetaJ*deltax*drI(i+1+k,j);
+	  if(Jder<numExtraDerKeep)
+	    d2r(i+1+Jder,j)-=neg_two_thetaJ*drI(i,j); //minus a negative is
+ 	    //a positive is correct, this extra term is for Jder=k
+	}
+      }
+    }
+  } else if(corrFunc==EXP_CORR_FUNC) {
+    std::cerr << "The exponential correlation function is not a valid correlation function for gradient enhanced Kriging\n";
+      assert(false);
+  } else if(corrFunc==POW_EXP_CORR_FUNC) {
+    std::cerr << "The powered exponential (with power < 2) correlation function is not a valid correlation function for gradient enhanced Kriging\n";
+      assert(false);
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)) {
+    // *********************************************************************
+    // The MATERN 3/2 CORRELATION FUNCTION
+    //
+    // the 1st derivative with respect to xr of the 1D correlation function
+    // is defined
+    //
+    // The 2nd derivative with respect to xr of the 1D correlation function
+    // *is undefined at xr==XR,
+    // *is -theta^2*(1-theta*|xr-XR|)*exp(-theta*|xr-XR|) at xr=/=XR
+    // *approaches -theta^2 from above and below
+    // when xr==XR we use the limit, -theta^2
+    // this follows the approach of
+    //   Lockwood, Brian A. and Anitescu, Mihai, "Gradient-Enhanced
+    //      Universal Kriging for Uncertainty Proagation"
+    //      Preprint ANL/MCS-P1808-1110
+    // *********************************************************************
+    double thetaJ=correlations(Jder,0);
+    double thetaJ_squared=thetaJ*thetaJ;
+    double thetaJ_abs_dx;
+    if(numVarsr==1) {
+      // if there is only one input variable we are taking the 2nd derivative
+      // of the 1D GEK correlation function (which contains first derivatives
+      // of the Kriging r with respect to XR) AND WE KNOW THAT Ider=Jder=k so
+      // we don't have to "if" to known when to give the 2nd derivative of
+      // GEK r = 3rd derivative of Kriging r, special treatment
+      double thetaJ_cubed=thetaJ_squared*thetaJ;
+      double r_div_matern_coef;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  r_div_matern_coef=r(i,j)/(1.0+thetaJ_abs_dx);
+	  d2r(i  ,j)=r_div_matern_coef*thetaJ_squared*(thetaJ_abs_dx-1.0);
+	  d2r(i+1,j)=r_div_matern_coef*thetaJ_cubed*dsign(deltax)*
+	    (thetaJ_abs_dx-2.0);
+	}
+	// since there is only one dimension if there is a partial point
+	// it will be a function value only, and actually recalculating it
+	// will likely be faster on average then checking if there's a
+	// partial point and calculating it if needed
+	ipt=numPointsKeep-1;
+	i=ipt*2;
+	thetaJ_abs_dx=thetaJ*std::fabs(xr(Jder,j)-XRreorder(Jder,ipt));
+	d2r(i,j)=r(i,j)/(1.0+thetaJ_abs_dx)*thetaJ_squared*(thetaJ_abs_dx-1.0);
+      }
+    } else if(Ider==Jder) {
+      // taking the 2nd derivative of the 1D correlation function of the GEK
+      // (not Kriging) r, which itself contains derivative of the Kriging r
+      // with respect to XR, but this 2nd derivative is indepedent of those
+      // first derivatives in all but one dimension
+      double thetaJ_cubed=thetaJ_squared*thetaJ;
+      double matern_coef;
+      double d2_mult_r;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  matern_coef=(1.0+thetaJ_abs_dx);
+	  d2_mult_r=thetaJ_squared*(thetaJ_abs_dx-1.0)/matern_coef;
+	  d2r(i,j)=r(i,j)*d2_mult_r;
+	  for(k=0; k<numVarsr; ++k) //this k loop assumes that the current
+	    //dimension is independent of the one that the XR derivative was
+	    //taken with respect to, it's correct for all but one k
+	    d2r(i+1+k,j)=r(i+1+k,j)*d2_mult_r;
+	  //rather than having an if inside the loop which is slow, we're just
+	  //going to reassign the d2r for k==Jder like this
+	  d2r(i+1+Jder,j)=r(i,j)* //indexes of r(i,j) are correct
+	    (thetaJ_cubed*dsign(deltax)*(thetaJ_abs_dx-2.0)/matern_coef);
+	}
+
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should already have the values we need them to
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  matern_coef=(1.0+thetaJ_abs_dx);
+	  d2_mult_r=thetaJ_squared*(thetaJ_abs_dx-1.0)/matern_coef;
+	  d2r(i,j)=r(i,j)*d2_mult_r;
+	  for(k=0; k<numExtraDerKeep; ++k) //this k loop assumes that the
+	    //current dimension is independent of the one that the XR
+	    //derivative was taken with respect to
+	    d2r(i+1+k,j)=r(i+1+k,j)*d2_mult_r;
+	  if(Jder<numExtraDerKeep) //if the dimension we're now taking a
+	    //derivative with respect to wasn't clipped from the partial point
+	    //we need to correct/reassign it for k==Jder
+	    d2r(i+1+Jder,j)=r(i,j)* //indexes of r(i,j) are correct
+	      (thetaJ_cubed*dsign(deltax)*(thetaJ_abs_dx-2.0)/matern_coef);
+	}
+      }
+    } else {
+      // taking the product of the 1st derivative (for GEK) of 2 independent
+      // 1D correlation functions (they're independent because Jder!=Ider).
+      // But since the GEK r contains first derivatives of the Kriging r,
+      // there is one dimension, k==Jder, that needs special treatment
+      double matern_coef;
+      double d1_mult_r;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  matern_coef=1.0+thetaJ_abs_dx;
+	  d1_mult_r=-thetaJ_squared*deltax/matern_coef;
+	  d2r(i,j)=drI(i,j)*d1_mult_r;
+	  for(k=0; k<numVarsr; ++k)  //this k loop assumes that the
+	    //current dimension is independent of the one that the XR
+	    //derivative was taken with respect to
+	    d2r(i+1+k,j)=drI(i+1+k,j)*d1_mult_r;
+	  //rather than having an if inside the loop which is slow, we're just
+	  //going to reassign the d2r for k==Jder like this
+	  d2r(i+1+Jder,j)=drI(i,j)* //indexes of drI(i,j) are correct
+	    thetaJ_squared*(1.0-thetaJ_abs_dx)/matern_coef; //sign is
+	    //opposite the numVarsr==1 d2r(i,j) because one of the 2
+	    //derivatives is taken with respect to XR instead of xr
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should already have the values we need them to
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  matern_coef=1.0+thetaJ_abs_dx;
+	  d1_mult_r=-thetaJ_squared*deltax/matern_coef;
+	  d2r(i,j)=drI(i,j)*d1_mult_r;
+	  for(k=0; k<numExtraDerKeep; ++k) //this k loop assumes that the
+	    //current dimension is independent of the one that the XR
+	    //derivative was taken with respect to
+	    d2r(i+1+k,j)=drI(i+1+k,j)*d1_mult_r;
+	  if(Jder<numExtraDerKeep)  //if the dimension we're now taking a
+	    //derivative with respect to wasn't clipped from the partial point
+	    //we need to correct/reassign it for k==Jder
+	    d2r(i+1+Jder,j)=drI(i,j)* //indexes of drI(i,j) are correct
+	      thetaJ_squared*(1.0-thetaJ_abs_dx)/matern_coef;
+	}
+      }
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)) {
+    // *********************************************************************
+    // The MATERN 5/2 CORRELATION FUNCTION
+    //
+    // the 1st and 2nd derivatives with respect to xr of the 1D correlation
+    // function are defined,
+    // 3rd derivative of Kriging r technically not defined at xr==XR (it is
+    // defined everywhere else) but the limit from both sides is defined and
+    // goes to zero at xr==XR (which means the limit from both sides agree)
+    // so we'll use the else where defined 3rd derivative even at xr==XR
+    // *********************************************************************
+    double thetaJ=correlations(Jder,0);
+    double thetaJ_squared=thetaJ*thetaJ;
+    double thetaJ_abs_dx;
+    if(numVarsr==1) {
+      // if there is only one input variable we are taking the 2nd derivative
+      // of the 1D GEK correlation function (which contains first derivatives
+      // of the Kriging r with respect to XR) AND WE KNOW THAT Ider=Jder=k so
+      // we don't have to "if" to known when to give the 2nd derivative of
+      // GEK r = 3rd derivative of Kriging r, special treatment
+      double r_thetaJ_squared_div_3_matern_coef;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=2) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  r_thetaJ_squared_div_3_matern_coef=r(i,j)*thetaJ_squared/
+	    (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx);
+	  d2r(i  ,j)=r_thetaJ_squared_div_3_matern_coef*
+	    -(1.0+thetaJ_abs_dx-thetaJ_abs_dx*thetaJ_abs_dx);
+	  d2r(i+1,j)=r_thetaJ_squared_div_3_matern_coef*
+	    -thetaJ_squared*deltax*(3.0-thetaJ_abs_dx);
+	}
+	// since there is only one dimension, if there is a partial point
+	// it will be a function value only, and actually recalculating it
+	// will likely be faster on average then checking if there's a
+	// partial point and calculating it if needed
+	ipt=numPointsKeep-1;
+	i=ipt*2;
+	thetaJ_abs_dx=thetaJ*std::fabs(xr(Jder,j)-XRreorder(Jder,ipt));
+	d2r(i,j)=r(i,j)*thetaJ_squared/
+	  (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx)*
+	  -(1.0+thetaJ_abs_dx-thetaJ_abs_dx*thetaJ_abs_dx);
+      }
+    } else if(Ider==Jder) {
+      // taking the 2nd derivative of the 1D correlation function of the GEK
+      // (not Kriging) r, which itself contains derivative of the Kriging r
+      // with respect to XR, but this 2nd derivative is indepedent of those
+      // first derivatives in all but one dimension
+      double neg_thetaJ_squared_div_3_matern_coef;
+      double d2_mult_r;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  neg_thetaJ_squared_div_3_matern_coef=-thetaJ_squared/
+	    (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx);
+	  d2_mult_r=neg_thetaJ_squared_div_3_matern_coef*
+	    (1.0+thetaJ_abs_dx-thetaJ_abs_dx*thetaJ_abs_dx);
+	  d2r(i,j)=r(i,j)*d2_mult_r;
+	  for(k=0; k<numVarsr; ++k) //this k loop assumes that the current
+	    //dimension is independent of the one that the XR derivative was
+	    //taken with respect to, it's correct for all but one k
+	    d2r(i+1+k,j)=r(i+1+k,j)*d2_mult_r;
+	  //rather than having an if inside the loop which is slow, we're just
+	  //going to reassign the d2r for k==Jder like this
+	  d2r(i+1+Jder,j)=r(i,j)* //indexes of r(i,j) are correct
+	    neg_thetaJ_squared_div_3_matern_coef*
+	    thetaJ_squared*deltax*(3.0-thetaJ_abs_dx);
+	}
+
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should already have the values we need them to
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  neg_thetaJ_squared_div_3_matern_coef=-thetaJ_squared/
+	    (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx);
+	  d2_mult_r=neg_thetaJ_squared_div_3_matern_coef*
+	    (1.0+thetaJ_abs_dx-thetaJ_abs_dx*thetaJ_abs_dx);
+	  d2r(i,j)=r(i,j)*d2_mult_r;
+	  for(k=0; k<numExtraDerKeep; ++k) //this k loop assumes that the
+	    //current dimension is independent of the one that the XR
+	    //derivative was taken with respect to
+	    d2r(i+1+k,j)=r(i+1+k,j)*d2_mult_r;
+	  if(Jder<numExtraDerKeep) //if the dimension we're now taking a
+	    //derivative with respect to wasn't clipped from the partial point
+	    //we need to correct/reassign it for k==Jder
+	    d2r(i+1+Jder,j)=r(i,j)* //indexes of r(i,j) are correct
+	      neg_thetaJ_squared_div_3_matern_coef*
+	      thetaJ_squared*deltax*(3.0-thetaJ_abs_dx);
+	}
+      }
+    } else {
+      // taking the product of the 1st derivative (for GEK) of 2 independent
+      // 1D correlation functions (they're independent because Jder!=Ider).
+      // But since the GEK r contains first derivatives of the Kriging r,
+      // there is one dimension, k==Jder, that needs special treatment
+      double thetaJ_squared_div_3_matern_coef;
+      double d1_mult_r;
+      for(j=0; j<nptsxr; ++j) {
+	for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt, i+=neqn_per_pt) {
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  thetaJ_squared_div_3_matern_coef=thetaJ_squared/
+	    (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx);
+	  d1_mult_r=-thetaJ_squared_div_3_matern_coef*
+	    deltax*(1.0+thetaJ_abs_dx);
+	  d2r(i,j)=drI(i,j)*d1_mult_r;
+	  for(k=0; k<numVarsr; ++k)  //this k loop assumes that the
+	    //current dimension is independent of the one that the XR
+	    //derivative was taken with respect to
+	    d2r(i+1+k,j)=drI(i+1+k,j)*d1_mult_r;
+	  //rather than having an if inside the loop which is slow, we're just
+	  //going to reassign the d2r for k==Jder like this
+	  d2r(i+1+Jder,j)=drI(i,j)* //indexes of drI(i,j) are correct
+	    thetaJ_squared_div_3_matern_coef*
+	    (1.0+thetaJ_abs_dx-thetaJ_abs_dx*thetaJ_abs_dx); //sign is
+	    //opposite the numVarsr==1 d2r(i,j) because one of the 2
+	    //derivatives is taken with respect to XR instead of xr
+	}
+	if(numPointsKeep>numWholePointsKeep) {
+	  //ipt and i should already have the values we need them to
+#ifdef __KRIG_ERR_CHECK__
+	  assert((ipt==numWholePointsKeep)&&
+		 (ipt==numPointsKeep-1)&&
+		 (i==neqn_per_pt*numWholePointsKeep));
+#endif
+	  deltax=xr(Jder,j)-XRreorder(Jder,ipt);
+	  thetaJ_abs_dx=thetaJ*std::fabs(deltax);
+	  thetaJ_squared_div_3_matern_coef=thetaJ_squared/
+	    (3.0*(1.0+thetaJ_abs_dx)+thetaJ_abs_dx*thetaJ_abs_dx);
+	  d1_mult_r=-thetaJ_squared_div_3_matern_coef*
+	    deltax*(1.0+thetaJ_abs_dx);
+	  d2r(i,j)=drI(i,j)*d1_mult_r;
+	  for(k=0; k<numExtraDerKeep; ++k) //this k loop assumes that the
+	    //current dimension is independent of the one that the XR
+	    //derivative was taken with respect to
+	    d2r(i+1+k,j)=drI(i+1+k,j)*d1_mult_r;
+	  if(Jder<numExtraDerKeep)  //if the dimension we're now taking a
+	    //derivative with respect to wasn't clipped from the partial point
+	    //we need to correct/reassign it for k==Jder
+	    d2r(i+1+Jder,j)=drI(i,j)* //indexes of drI(i,j) are correct
+	      thetaJ_squared_div_3_matern_coef*
+	      (1.0+thetaJ_abs_dx-thetaJ_abs_dx*thetaJ_abs_dx);
+	}
+      }
+    }
+  } else{
+    std::cerr << "unknown corrFunc in MtxDbl& KrigingModel::eval_gek_d2correlation_matrix_dxIdxJ(MtxDbl& d2r, const MtxDbl& drI, const MtxDbl& r, const MtxDbl& xr, int Ider, int Jder) const\n";
+    assert(false);
+  }
+  return d2r;
+}
+
+
+
+/** this function is typically used during emulator construction, the below
+    the diagonal portion of R = exp(Z^T*theta), where R is symmetric with 1's
+    on the diagonal, theta is the vector of correlations and the Z matrix is
+    defined as Z(k,ij)=-(XR(k,i)-XR(k,j))^2 where ij counts downward within
+    columns of R starting from the element below the diagonal and continues
+    from one column to the next, Z^T*theta is matrix vector multiplication to
+    be performed efficiently by BLAS, V=Z^T*theta is a vector with
+    nchoosek(numPoints,2) elements.  We need to copy exp(V(ij)) to R(i,j)
+    and R(j,i) to produce R. The Z matrix is produced by
+    KrigingModel::gen_Z_matrix()     KRD wrote this */
+void KrigingModel::correlation_matrix(const MtxDbl& theta)
+{
+  int ncolsZ=Z.getNCols();
+  //printf("nrowsZ=%d; numPoints=%d; ''half'' numPoints^2=%d; numVarsr=%d; theta.getNRows()=%d\n",
+  //	 ncolsZ,numPoints,nchoosek(numPoints,2),numVarsr,theta.getNRows());
+  //fflush(stdout);
+#ifdef __KRIG_ERR_CHECK__
+  assert((ncolsZ==nchoosek(numPoints,2))&&
+	 (numVarsr==Z.getNRows())&&
+	 (numVarsr==theta.getNRows())&&
+	 (1==theta.getNCols()));
+#endif
+
+  Ztran_theta.newSize(ncolsZ,1); //Z transpose because subsequent access of a
+  //column vector should be marginally faster than a row vector
+  matrix_mult(Ztran_theta,Z,theta,0.0,1.0,'T','N');
+
+  if(buildDerOrder==0)
+    numRowsR=numPoints;
+  else if(buildDerOrder==1)
+    numRowsR=numPoints*nDer;
+  else{
+    std::cerr << "buildDerOrder=" << buildDerOrder << " in void KrigingModel::correlation_matrix(const MtxDbl& theta).  It must either be 0 for Kriging or 1 for Gradient Enhanced Kriging.  Higher order build derivatives, (e.g. Hessian Enhanced Kriging) have not been implemented." << std::endl;
+    assert(false);
+  }
+  R.newSize(numRowsR,numRowsR);
+
+  //Do the regular (Der0) Kriging Portion of the Correlation matrix first
+  double Rij_temp;
+  int ij=0;
+  if((corrFunc==GAUSSIAN_CORR_FUNC)||
+     (corrFunc==EXP_CORR_FUNC)||
+     (corrFunc==POW_EXP_CORR_FUNC)) {
+    for(int j=0; j<numPoints-1; ++j) {
+      R(j,j)=1.0;
+      for(int i=j+1; i<numPoints; ++i, ++ij) {
+	Rij_temp=std::exp(Ztran_theta(ij,0));
+	R(i,j)=Rij_temp;
+	R(j,i)=Rij_temp;
+      }
+    }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)){
+    //for matern Z(k,ij)=-|XR(k,i)-XR(k,j)| we want to feed
+    //theta(k,0)*|XR(k,i)-XR(k,j)| to matern_1pt5_coef so we need to
+    //negate the already negative quantity
+    if(numVarsr==1)
+      for(int j=0; j<numPoints-1; ++j) {
+	R(j,j)=1.0;
+	for(int i=j+1; i<numPoints; ++i, ++ij) {
+	  Rij_temp=std::exp(Ztran_theta(ij,0))*
+	    matern_1pt5_coef(-Ztran_theta(ij,0));
+	  R(i,j)=Rij_temp;
+	  R(j,i)=Rij_temp;
+	}
+      }
+    else
+      for(int j=0; j<numPoints-1; ++j) {
+	R(j,j)=1.0;
+	for(int i=j+1; i<numPoints; ++i, ++ij) {
+	  Rij_temp=std::exp(Ztran_theta(ij,0))*
+	    matern_1pt5_coef(-Z(0,ij)*theta(0,0));
+	  for(int k=1; k<numVarsr; ++k)
+	    Rij_temp*=matern_1pt5_coef(-Z(k,ij)*theta(k,0));
+	  R(i,j)=Rij_temp;
+	  R(j,i)=Rij_temp;
+	}
+      }
+  } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)){
+    //for matern Z(k,ij)=-|XR(k,i)-XR(k,j)| we want to feed
+    //theta(k,0)*|XR(k,i)-XR(k,j)| to matern_2pt5_coef so we need to
+    //negate the already negative quantity
+    if(numVarsr==1)
+      for(int j=0; j<numPoints-1; ++j) {
+	R(j,j)=1.0;
+	for(int i=j+1; i<numPoints; ++i, ++ij) {
+	  Rij_temp=std::exp(Ztran_theta(ij,0))*
+	    matern_2pt5_coef(-Ztran_theta(ij,0));
+	  R(i,j)=Rij_temp;
+	  R(j,i)=Rij_temp;
+	}
+      }
+    else
+      for(int j=0; j<numPoints-1; ++j) {
+	R(j,j)=1.0;
+	for(int i=j+1; i<numPoints; ++i, ++ij) {
+	  Rij_temp=std::exp(Ztran_theta(ij,0))*
+	    matern_2pt5_coef(-Z(0,ij)*theta(0,0));
+	  for(int k=1; k<numVarsr; ++k)
+	    Rij_temp*=matern_2pt5_coef(-Z(k,ij)*theta(k,0));
+	  R(i,j)=Rij_temp;
+	  R(j,i)=Rij_temp;
+	}
+      }
+  }else{
+    std::cerr << "unknown corrFunc in void KrigingModel::correlation_matrix(const MtxDbl& theta)\n";
+    assert(false);
+  }
+  R(numPoints-1,numPoints-1)=1.0;
+
+  /*
+  FILE *fp=fopen("km_Rmat_check.txt","w");
+  for(int i=0; i<numPoints; ++i) {
+      fprintf(fp,"%-12.6g", R(i,0));
+      for(int j=1; j<numPoints; ++j)
+	fprintf(fp," %-12.6g", R(i,j));
+      fprintf(fp,"\n");
+  }
+  fclose(fp);
+  */
+
+  if(buildDerOrder>0) {
+    //Gaussian Matern1.5 and Matern2.5 are valid correlation functions for
+    //Gradient Enhanced Kriging
+    double temp_double;
+    int zij, j;
+
+
+    if(corrFunc==GAUSSIAN_CORR_FUNC) {
+      //now handle the first order derivative submatrices, indiviually the first
+      //order derivative SUBmatrices are anti-symmetric but the whole matrix is
+      //symmetric
+      int Ii, Ij, Jj, Ji; //first letter identifies index OF derivative submatrix
+      //second letter identifies index INTO derivative SUBmatrix
+      for(int Ider=0; Ider<numVarsr; ++Ider) {
+	zij=0;
+	double two_theta_Ider=2.0*theta(Ider,0);
+	for(j=0; j<numPoints-1; ++j) {//j<numPoints-1 avoids an i loop of length 0
+	  //diagonal (_j,_j) of off diagonal (I_, _) submatrix
+	  Ij=(Ider+1)*numPoints+j;
+	  R(Ij, j)=0.0;
+	  R( j,Ij)=0.0;
+	  //Ij=(Ider+1)*numPoints+j;
+	  for(int i=j+1; i<numPoints; ++i, ++zij) {
+	    //off diagonal (_i,_j) of off-diagonal (I_, _) submatrix
+	    Ii=(Ider+1)*numPoints+i;
+	    temp_double=-two_theta_Ider*deltaXR(zij,Ider)*R( i, j);
+	    //here  temp_double=
+	    //                  R(Ii, j) = dR(i,j)/dXR1(Ider,i)
+	    //                  R( j,Ii) = dR(i,j)/dXR2(Ider,j)
+	    //and  -temp_double=
+	    //                  R(Ij, i) = dR(i,j)/dXR1(Ider,j)
+	    //                  R( i,Ij) = dR(i,j)/dXR2(Ider,i)
+	    //where XR1 is the first argument of the correlation function
+	    //and XR2 is the second argument of the correlation function
+	    R(Ii, j)= temp_double;
+	    R( j,Ii)= temp_double; //whole R matrix is symmetric
+	    R(Ij, i)=-temp_double;
+	    R( i,Ij)=-temp_double; //off-diagonal 1st order (actually all odd
+	    //order) derivative SUBmatrices are anti-symmetric
+	  }
+	}
+	//diagonal (_j,_j) of off diagonal (I_, _) submatrix
+	j=numPoints-1; //avoids an i loop of length 0
+	Ij=(Ider+1)*numPoints+j;
+	R(Ij,j)=0.0;
+	R(j,Ij)=0.0;
+      }
+
+      //note that all 2nd order (actually all even order) derivative SUBmatrices
+      //are symmetric because the hadamard product of 2 (actually any even
+      //number of) anti-symmetric matrices is a symmetric matrix
+      double two_theta_Jder;
+      for(int Jder=0; Jder<numVarsr; ++Jder) {
+	//do the on diagonal (J_,J_) submatrix
+	two_theta_Jder=2.0*theta(Jder,0);
+	zij=0;
+	for(j=0; j<numPoints-1; ++j) { //j<numPoints-1 avoids an i loop of length 0
+	  //diagonal (_j,_j) of on diagonal (J_,J_) submatrix
+	  Jj=(Jder+1)*numPoints+j;
+	  R(Jj,Jj)=two_theta_Jder; //R(Jj,Jj)=2*theta(Jder,0)*R(j,j); R(j,j)=1;
+	  for(int i=j+1; i<numPoints; ++i) {
+	    //off diagonal (_i,_j) of on-diagonal (J_,J_) submatrix
+	    Ji=(Jder+1)*numPoints+i;
+	    temp_double=two_theta_Jder*deltaXR(zij,Jder)*R(Ji, j)+
+	    two_theta_Jder*R( i, j);
+	    R(Ji,Jj)=temp_double;
+	    R(Jj,Ji)=temp_double;
+	    ++zij;
+	  }
+	}
+	//diagonal (_j,_j) of on diagonal (J_,J_) submatrix
+	j=numPoints-1; //avoids an i loop of length 0
+	Jj=(Jder+1)*numPoints+j;
+	R(Jj,Jj)=two_theta_Jder; //R(j,j)=1 R(Jj,Jj)=2*theta(Jder,0)*R(j,j)
+
+
+	//do the off diagonal (I_,J_) submatrices
+	for(int Ider=Jder+1; Ider<numVarsr; ++Ider) {
+	  //off diagonal (I_,J_) submatrix
+	  zij=0;
+	  for(j=0; j<numPoints-1; ++j) {//j<numPoints-1 avoids an i loop of length 0
+	    //diagonal (_j,_j) of off-diagonal (I_,J_) submatrix
+	    Jj=(Jder+1)*numPoints+j;
+	    Ij=(Ider+1)*numPoints+j;
+	    R(Ij,Jj)=0.0;
+	    R(Jj,Ij)=0.0;
+
+
+	    for(int i=j+1; i<numPoints; ++i) {
+	      //off diagonal (_i,_j) of off-diagonal (I_,J_) submatrix
+	      Ii=(Ider+1)*numPoints+i;
+	      Ji=(Jder+1)*numPoints+i;
+	      temp_double=two_theta_Jder*deltaXR(zij,Jder)*R(Ii, j);
+	      R(Ii,Jj)= temp_double;
+	      R(Ij,Ji)= temp_double;
+	      R(Ji,Ij)= temp_double;
+	      R(Jj,Ii)= temp_double;
+	      ++zij;
+	    }
+	  }
+	  //diagonal (_j,_j) of off-diagonal (I_,J_) submatrix
+	  j=numPoints-1; //avoids an i loop of length 0
+	  Ij=(Ider+1)*numPoints+j;
+	  Jj=(Jder+1)*numPoints+j;
+	  R(Ij,Jj)=0.0;
+	  R(Jj,Ij)=0.0;
+	}
+      }
+    } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==1.5)) {
+      //The second derivative of the Matern1.5 correlation function
+      //is not strictly defined at XR(i,Ider)==XR(j,Jder) but the limit
+      //of the second derivative from both sides is defined and is the same
+      //this follows
+      //Lockwood, Brian A. and Anitescu, Mihai, "Gradient-Enhanced
+      //    Universal Kriging for Uncertainty Proagation"
+      //    Preprint ANL/MCS-P1808-1110
+      //
+      //d2r_dXIdXJ with Ider==Jder
+      // = theta^2*exp(-theta*|XI-XJ|)-theta^3*|XI-XJ|*exp(-theta*|XI-XJ|)
+      // = -theta^2*(1-2/matern_1pt5_coef)*r(XI,XJ)
+      // = -matern_1pt5_d2_mult_r(theta,+/-(XI-XJ))*r(XI,XJ) (note the
+      //    negative sign, it should be here, but does not appear when
+      //    evalutation 2nd derivative of GP, because there it is second
+      //    derivative with respect to the SAME argument, here it is the
+      //    second derivative with respect to different arguments)
+
+      //now handle the first order derivative submatrices, indiviually the first
+      //order derivative SUBmatrices are anti-symmetric but the whole matrix is
+      //symmetric
+      int Ii, Ij, Jj, Ji; //first letter identifies index OF derivative
+      //submatrix second letter identifies index INTO derivative SUBmatrix
+      for(int Ider=0; Ider<numVarsr; ++Ider) {
+	zij=0;
+	double theta_Ider=theta(Ider,0);
+	for(j=0; j<numPoints-1; ++j) {//j<numPoints-1 avoids an i loop of
+	  //length 0
+
+	  //diagonal (_j,_j) of off diagonal (I_, _) submatrix
+	  Ij=(Ider+1)*numPoints+j;
+	  R(Ij, j)=0.0;
+	  R( j,Ij)=0.0;
+	  //Ij=(Ider+1)*numPoints+j;
+	  for(int i=j+1; i<numPoints; ++i) {
+	    //off diagonal (_i,_j) of off-diagonal (I_, _) submatrix
+	    Ii=(Ider+1)*numPoints+i;
+	    temp_double=
+	      matern_1pt5_d1_mult_r(theta_Ider,deltaXR(zij,Ider))*R( i, j);
+	    R(Ii, j)= temp_double;
+	    R( j,Ii)= temp_double; //whole R matrix is symmetric
+	    R(Ij, i)=-temp_double;
+	    R( i,Ij)=-temp_double; //off-diagonal 1st order (actually all odd
+	    //order) derivative SUBmatrices are anti-symmetric
+	    ++zij;
+	  }
+	}
+	//diagonal (_j,_j) of off diagonal (I_, _) submatrix
+	j=numPoints-1; //avoids an i loop of length 0
+	Ij=(Ider+1)*numPoints+j;
+	R(Ij, j)=0.0;
+	R( j,Ij)=0.0;
+      }
+
+      //note that all 2nd order (actually all even order) derivative SUBmatrices
+      //are symmetric because the hadamard product of 2 (actually any even
+      //number of) anti-symmetric matrices is a symmetric matrix
+      double theta_Jder;
+      double theta_Jder_squared;
+      for(int Jder=0; Jder<numVarsr; ++Jder) {
+	//do the on diagonal (J_,J_) submatrix
+	theta_Jder=theta(Jder,0);
+	theta_Jder_squared=theta_Jder*theta_Jder;
+	zij=0;
+	for(j=0; j<numPoints-1; ++j) { //j<numPoints-1 avoids an i loop of length 0
+	  //diagonal (_j,_j) of on diagonal (J_,J_) submatrix
+	  Jj=(Jder+1)*numPoints+j;
+	  R(Jj,Jj)=theta_Jder_squared;
+	  for(int i=j+1; i<numPoints; ++i) {
+	    //off diagonal (_i,_j) of on-diagonal (J_,J_) submatrix
+	    Ji=(Jder+1)*numPoints+i;
+	    temp_double=//neg sign because d^2/dXR1dXR2 instead of d^2/dXR1^2
+	      -matern_1pt5_d2_mult_r(theta_Jder,deltaXR(zij,Jder))*R( i, j);
+	    R(Ji,Jj)=temp_double;
+	    R(Jj,Ji)=temp_double;
+	    ++zij;
+	  }
+	}
+	//diagonal (_j,_j) of on diagonal (J_,J_) submatrix
+	j=numPoints-1; //avoids an i loop of length 0
+	Jj=(Jder+1)*numPoints+j;
+	R(Jj,Jj)=theta_Jder_squared;
+
+
+	//do the off diagonal (I_,J_) submatrices
+	for(int Ider=Jder+1; Ider<numVarsr; ++Ider) {
+	  //off diagonal (I_,J_) submatrix
+	  zij=0;
+	  for(j=0; j<numPoints-1; ++j) {//j<numPoints-1 avoids an i loop of length 0
+	    //diagonal (_j,_j) of off-diagonal (I_,J_) submatrix
+	    Jj=(Jder+1)*numPoints+j;
+	    Ij=(Ider+1)*numPoints+j;
+	    R(Ij,Jj)=0.0;
+	    R(Jj,Ij)=0.0;
+
+	    for(int i=j+1; i<numPoints; ++i) {
+	      //off diagonal (_i,_j) of off-diagonal (I_,J_) submatrix
+	      Ii=(Ider+1)*numPoints+i;
+	      Ji=(Jder+1)*numPoints+i;
+	      temp_double=
+		matern_1pt5_d1_mult_r(theta_Jder,-deltaXR(zij,Jder))*R(Ii, j);
+	      R(Ii,Jj)= temp_double;
+	      R(Ij,Ji)= temp_double;
+	      R(Ji,Ij)= temp_double;
+	      R(Jj,Ii)= temp_double;
+	      ++zij;
+	    }
+	  }
+	  //diagonal (_j,_j) of off-diagonal (I_,J_) submatrix
+	  j=numPoints-1; //avoids an i loop of length 0
+	  Ij=(Ider+1)*numPoints+j;
+	  Jj=(Jder+1)*numPoints+j;
+	  R(Ij,Jj)=0.0;
+	  R(Jj,Ij)=0.0;
+	}
+      }
+
+    } else if((corrFunc==MATERN_CORR_FUNC)&&(maternCorrFuncNu==2.5)) {
+      //now handle the first order derivative submatrices, indiviually the first
+      //order derivative SUBmatrices are anti-symmetric but the whole matrix is
+      //symmetric
+      int Ii, Ij, Jj, Ji; //first letter identifies index OF derivative
+      //submatrix second letter identifies index INTO derivative SUBmatrix
+      for(int Ider=0; Ider<numVarsr; ++Ider) {
+	zij=0;
+	double theta_Ider=theta(Ider,0);
+	for(j=0; j<numPoints-1; ++j) {//j<numPoints-1 avoids an i loop of
+	  //length 0
+
+	  //diagonal (_j,_j) of off diagonal (I_, _) submatrix
+	  Ij=(Ider+1)*numPoints+j;
+	  R(Ij, j)=0.0;
+	  R( j,Ij)=0.0;
+	  //Ij=(Ider+1)*numPoints+j;
+	  for(int i=j+1; i<numPoints; ++i) {
+	    //off diagonal (_i,_j) of off-diagonal (I_, _) submatrix
+	    Ii=(Ider+1)*numPoints+i;
+	    temp_double=
+	      matern_2pt5_d1_mult_r(theta_Ider,deltaXR(zij,Ider))*R( i, j);
+	    R(Ii, j)= temp_double;
+	    R( j,Ii)= temp_double; //whole R matrix is symmetric
+	    R(Ij, i)=-temp_double;
+	    R( i,Ij)=-temp_double; //off-diagonal 1st order (actually all odd
+	    //order) derivative SUBmatrices are anti-symmetric
+	    ++zij;
+	  }
+	}
+	//diagonal (_j,_j) of off diagonal (I_, _) submatrix
+	j=numPoints-1; //avoids an i loop of length 0
+	Ij=(Ider+1)*numPoints+j;
+	R(Ij, j)=0.0;
+	R( j,Ij)=0.0;
+      }
+
+      //note that all 2nd order (actually all even order) derivative SUBmatrices
+      //are symmetric because the hadamard product of 2 (actually any even
+      //number of) anti-symmetric matrices is a symmetric matrix
+      double theta_Jder;
+      double theta_Jder_squared_div_3;
+      for(int Jder=0; Jder<numVarsr; ++Jder) {
+	//do the on diagonal (J_,J_) submatrix
+	theta_Jder=theta(Jder,0);
+	theta_Jder_squared_div_3=theta_Jder*theta_Jder/3.0;
+	zij=0;
+	for(j=0; j<numPoints-1; ++j) { //j<numPoints-1 avoids an i loop of length 0
+	  //diagonal (_j,_j) of on diagonal (J_,J_) submatrix
+	  Jj=(Jder+1)*numPoints+j;
+	  R(Jj,Jj)=theta_Jder_squared_div_3;
+	  for(int i=j+1; i<numPoints; ++i) {
+	    //off diagonal (_i,_j) of on-diagonal (J_,J_) submatrix
+	    Ji=(Jder+1)*numPoints+i;
+	    temp_double=//neg sign because d^2/dXR1dXR2 instead of d^2/dXR1^2
+	      -matern_2pt5_d2_mult_r(theta_Jder,deltaXR(zij,Jder))*R( i, j);
+	    R(Ji,Jj)=temp_double;
+	    R(Jj,Ji)=temp_double;
+	    ++zij;
+	  }
+	}
+	//diagonal (_j,_j) of on diagonal (J_,J_) submatrix
+	j=numPoints-1; //avoids an i loop of length 0
+	Jj=(Jder+1)*numPoints+j;
+	R(Jj,Jj)=theta_Jder_squared_div_3;
+
+
+      	//do the off diagonal (I_,J_) submatrices
+	for(int Ider=Jder+1; Ider<numVarsr; ++Ider) {
+	  //off diagonal (I_,J_) submatrix
+	  zij=0;
+	  for(j=0; j<numPoints-1; ++j) {//j<numPoints-1 avoids an i loop of length 0
+	    //diagonal (_j,_j) of off-diagonal (I_,J_) submatrix
+	    Jj=(Jder+1)*numPoints+j;
+	    Ij=(Ider+1)*numPoints+j;
+	    R(Ij,Jj)=0.0;
+	    R(Jj,Ij)=0.0;
+
+	    for(int i=j+1; i<numPoints; ++i) {
+	      //off diagonal (_i,_j) of off-diagonal (I_,J_) submatrix
+	      Ii=(Ider+1)*numPoints+i;
+	      Ji=(Jder+1)*numPoints+i;
+	      temp_double=
+		matern_2pt5_d1_mult_r(theta_Jder,-deltaXR(zij,Jder))*R(Ii, j);
+	      R(Ii,Jj)= temp_double;
+	      R(Ij,Ji)= temp_double;
+	      R(Ji,Ij)= temp_double;
+	      R(Jj,Ii)= temp_double;
+	      ++zij;
+	    }
+	  }
+	  //diagonal (_j,_j) of off-diagonal (I_,J_) submatrix
+	  j=numPoints-1; //avoids an i loop of length 0
+	  Ij=(Ider+1)*numPoints+j;
+	  Jj=(Jder+1)*numPoints+j;
+	  R(Ij,Jj)=0.0;
+	  R(Jj,Ij)=0.0;
+	}
+      }
+    } else{
+      std::cerr << "Unknown or Invalid Correlation function for Gradient Enhanced Kriging in void KrigingModel::correlation_matrix(const MtxDbl& theta)\n";
+      assert(false);
+    }
+    /*
+    printf("theta=[%14.8g",theta(0,0));
+    for(int k=1; k<numVarsr; ++k)
+      printf(" %14.8g",theta(k,0));
+    printf("]^T\n");
+    printf("M3/2 GEK R=\n");
+    for(int i=0; i<numEqnAvail; ++i) {
+      for(int j=0; j<numEqnAvail; ++j)
+	printf("%14.8g ",R(i,j));
+      printf("\n");
+    }
+    printf("\n\n");
+    */
+
+  }
+
+  return;
+}
+
+/** the Z matrix is defined as Z(k,ij)=-(XR(i,k)-XR(j,k))^2 where
+    ij=i+j*XR.getNRows(), it enables the efficient repeated calculation
+    of the R matrix during model construction:
+    R=reshape(exp(Z*theta),XR.getNRows(),XR.getNRows()) where theta is
+    the vector of correlations and * is matrix vector multiplication,
+    note that the Z matrix is independent of the correlation vector so
+    it can be formed once and later during the search for a good
+    correlation vector, the matrix vector product Z*theta can be
+    performed efficiently (for each member of the set of candidate
+    theta vectors) by calling BLAS. Z and XR are member variables so
+    they don't need to be passed in, KRD wrote this,  */
+MtxDbl& KrigingModel::gen_Z_matrix()
+{
+#ifdef __KRIG_ERR_CHECK__
+  assert((XR.getNRows()==numVarsr)&&(XR.getNCols()==numPoints));
+#endif
+  int ncolsZ=nchoosek(numPoints,2);
+  Z.newSize(numVarsr,ncolsZ);
+
+  if(buildDerOrder>0) {
+    //deltaXR is only needed for GEK
+    deltaXR.newSize(ncolsZ,numVarsr); //this ordering (transpose of Z)
+    //is useful for constructing the GEK R matrix
+  }
+
+  int ij=0;
+  if(corrFunc==GAUSSIAN_CORR_FUNC)  {
+    // ****************************************************************
+    // The Gausssian Correlation Function
+    // can be used for Gradient Enhanced Kriging (GEK)
+    // (or more generally, for derivative enhanced Kriging) because
+    // it is C infinity continuous.
+    // It uses Z(k,ij) = -(XR(k,i)-XR(k,j))^2
+    // if GEK is used we will also compute and store
+    // deltaXR(ij,k) = XR(k,i)-XR(k,j), the order of indexes is correct
+    // this transposed ordering is useful for efficient computation of
+    // the GEK R matrix (using the SUBmatrix construction process)
+    // ****************************************************************
+    double dXR; //a temporary variable to make squaring easier
+    if(buildDerOrder>0)
+      for(int j=0; j<numPoints-1; ++j)
+	for(int i=j+1; i<numPoints; ++i, ++ij)
+	  for(int k=0; k<numVarsr; k++) {
+	    dXR=XR(k,i)-XR(k,j);
+	    deltaXR(ij,k)=dXR;
+	    Z(k,ij)=-dXR*dXR;
+	  }
+    else
+      for(int j=0; j<numPoints-1; ++j)
+	for(int i=j+1; i<numPoints; ++i, ++ij)
+	  for(int k=0; k<numVarsr; k++) {
+	    dXR=XR(k,i)-XR(k,j);
+	    Z(k,ij)=-dXR*dXR;
+	  }
+  } else if((corrFunc==EXP_CORR_FUNC)||(corrFunc==MATERN_CORR_FUNC)) {
+    // ****************************************************************
+    // The Exponential and Matern 3/2 and 5/2 Correlation Functions
+    // all use Z(k,ij) = -|XR(k,i)-XR(k,j)|
+    // the Exponential Correlation Function
+    //     can NOT be used for Gradient Enhanced Kriging (GEK)
+    // the Matern 3/2 and 5/2 Correlation Functions
+    //     CAN be used for Gradient Enhanced Kriging (GEK)
+    // if GEK is used we will also compute and store
+    //     deltaXR(ij,k) = XR(k,i)-XR(k,j), the order of indexes is
+    //     correct this transposed ordering is useful for efficient
+    //     computation of the GEK R matrix (using the SUBmatrix
+    //     construction process)
+    // ****************************************************************
+    if(buildDerOrder>0) {
+      if(corrFunc==EXP_CORR_FUNC) {
+	std::cerr << "the exponential correlation function is not a valid choice for Gradient Enhanced Kriging\n";
+	assert(!((corrFunc==EXP_CORR_FUNC)&&(buildDerOrder>0)));
+      }
+      for(int j=0; j<numPoints-1; ++j)
+	for(int i=j+1; i<numPoints; ++i, ++ij)
+	  for(int k=0; k<numVarsr; k++) {
+	    deltaXR(ij,k)=XR(k,i)-XR(k,j);
+	    Z(k,ij)=-std::fabs(deltaXR(ij,k));
+	  }
+    } else
+      for(int j=0; j<numPoints-1; ++j)
+	for(int i=j+1; i<numPoints; ++i, ++ij)
+	  for(int k=0; k<numVarsr; k++)
+	    Z(k,ij)=-std::fabs(XR(k,i)-XR(k,j));
+  } else if(corrFunc==POW_EXP_CORR_FUNC) {
+    // ****************************************************************
+    // The Powered Exponential Correlation Function
+    // uses Z(k,ij) = -(|XR(k,i)-XR(k,j)|^powExpCorrFuncPow)
+    // where 1.0<powExpCorrFuncPow<2.0
+    // It can NOT be used for Gradient Enhanced Kriging (GEK)
+    // ****************************************************************
+    if(buildDerOrder>0) {
+      std::cerr << "the powered exponential correlation function is not a valid choice for Gradient Enhanced Kriging\n";
+      assert(!((corrFunc==POW_EXP_CORR_FUNC)&&(buildDerOrder>0)));
+    }
+    for(int j=0; j<numPoints-1; ++j)
+      for(int i=j+1; i<numPoints; ++i, ++ij)
+	for(int k=0; k<numVarsr; k++)
+	  Z(k,ij)=-std::pow(std::fabs(XR(k,i)-XR(k,j)),powExpCorrFuncPow);
+  } else{
+    std::cerr << "unknown Correlation Function in MtxDbl& KrigingModel::gen_Z_matrix()\n";
+    assert(false);
+  }
+  return Z;
+}
+
+void KrigingModel::reorderCopyRtoRChol() {
+  numRowsR=numEqnAvail;
+  RChol.newSize(numRowsR,numRowsR);
+
+  if(buildDerOrder==0) {
+    //Kriging
+    for(int jpt=0; jpt<numPoints; ++jpt) {
+      int jsrc=iPtsKeep(jpt,0);
+      for(int ipt=0; ipt<numPoints; ++ipt)
+	RChol(ipt,jpt)=R(iPtsKeep(ipt,0),jsrc);
+    }
+  } else if(buildDerOrder==1) {
+    //Gradient Enhanced Kriging, R is blocked into (1+numVarsr) by (1+numVarsr)
+    //submatrices.  Each submatrix has numPoints by numPoints elements, i.e.
+    //the same size as the Kriging R matrix, in fact the upper-left-most
+    //submatrix is the Kriging R matrix, we need to reorder this so that
+    //"Whole Points" (a function value immediately followed by its gradient)
+    //are listed in the order given in iPtsKeep
+
+    int i, j;
+    for(int jpt=0, j=0; jpt<numPoints; ++jpt)
+      for(int jder=-1; jder<numVarsr; ++jder, ++j) {
+	int jsrc=iPtsKeep(jpt,0)+(jder+1)*numPoints;
+	for(int ipt=0, i=0; ipt<numPoints; ++ipt)
+	  for(int ider=-1; ider<numVarsr; ++ider, ++i)
+	    RChol(i,j)=R(iPtsKeep(ipt,0)+(ider+1)*numPoints,jsrc);
+      }
+  } else {
+    std::cerr << "buildDerOrder=" << buildDerOrder
+	      << " in void KrigingModel::reorderCopyRtoRChol(); "
+	      << "for Kriging buildDerOrder must be 0; "
+	      << "for Gradient Enhanced Kriging buildDerOrder must be 1; "
+	      << "Higher order derivative enhanced Kriging "
+	      << "(e.g Hessian Enhanced Kriging) has not been implemented"
+	      << std::endl;
+    assert(false);
+  }
+  return;
+}
+
+void KrigingModel::nuggetSelectingCholR(){
+  if(buildDerOrder==0)
+    numExtraDerKeep=0;
+  else if(buildDerOrder==1)
+    numExtraDerKeep=numVarsr; //the last point will have all of the gradient
+  else{
+    std::cerr << "buildDerOrder=" << buildDerOrder
+	      << " in void KrigingModel::nuggetSelectingCholR(); "
+	      << "for Kriging buildDerOrder must be 0; "
+	      << "for Gradient Enhanced Kriging buildDerOrder must be 1; "
+	      << "Higher order derivative enhanced Kriging "
+	      << "(e.g Hessian Enhanced Kriging) has not been implemented"
+	      << std::endl;
+    assert(false);
+  }
+  numWholePointsKeep=numPointsKeep=numPoints;
+
+  double min_allowed_rcond=1.0/maxCondNum;
+  int ld_RChol=RChol.getNRowsAct();
+  rcondDblWork.newSize(3*ld_RChol,1);
+  rcondIntWork.newSize(ld_RChol,1);
+  scaleRChol.newSize(numEqnAvail,1); //scaling/equilibrating is only
+  //necessary if GEK is used (because Kriging already has all ones on
+  //the diagonal of R; GEK doesn't) but the generic Cholesky
+  //factorization won't know in advance whether it's needed or not
+  //you can calculate rcond essentially "for free" if you do it at the
+  //same time as the Cholesky factorization
+  int chol_info;
+
+  //point order is the default point order
+  for(int ipt=0; ipt<numPointsKeep; ++ipt)
+    iPtsKeep(ipt,0)=ipt;
+  if(ifAssumeRcondZero==true)
+    rcondR=0.0;
+  else {
+    //but if GEK is used I still need to reorder from derivative submatrix
+    //blocks to whole point order
+    reorderCopyRtoRChol();
+
+    //See the end of the KrigingModel constructor for why Y and Gtran are
+    //what we already need them to be.
+    //the maximumAllowedPolyOrder given the number of Points is already
+    //selected, and Gtran is already what we need it to be
+
+    nug=0.0;
+    Chol_fact_workspace(RChol,scaleRChol,rcondDblWork,rcondIntWork,
+			chol_info,rcondR);
+  }
+
+  //this rcondR is for the equilibrated R/RChol (so pretend it has all
+  //ones on the diagonal)
+  if(rcondR<=min_allowed_rcond) {
+    double dbl_num_eqn=static_cast<double>(numEqnAvail);
+    double sqrt_num_eqn=std::sqrt(dbl_num_eqn);
+    min_allowed_rcond*=sqrt_num_eqn; //one norm is within a factor of N^0.5
+    //of 2 norm
+    rcondR/=sqrt_num_eqn; //one norm is within a factor of N^0.5 of 2 norm
+    double min_eig_worst=(rcondR*dbl_num_eqn)/(1.0+(dbl_num_eqn-1.0)*rcondR);
+    double max_eig_worst=dbl_num_eqn-(dbl_num_eqn-1.0)*min_eig_worst;
+    nug=(min_allowed_rcond*max_eig_worst-min_eig_worst)/
+      (1.0-min_allowed_rcond);
+    //this nugget will make the worst case scenario meet (with an ==)
+    //the maxCondNum constraint, I (KRD) don't expect this to
+    //ever == fail because I don't expect rcond to be *N^-0.5 without
+    //nugget and be *N^0.5 with nugget while the maximum eigen value
+    //of R (without nugget) is N-(N-1)*min_eigval (that comes from
+    //assumming all eigenvalues except the largest are the smallest
+    //possible for the given rcond) note that rcond is the LAPACK
+    //ESTIMATE of the 1 norm condition number so there are no 100%
+    //guarantees.
+    apply_nugget_build(); //multiply the diagonal elements by (1.0+nug)
+    reorderCopyRtoRChol();
+
+    Chol_fact_workspace(RChol,scaleRChol,rcondDblWork,rcondIntWork,
+			chol_info,rcondR);
+  }
+  return;
+}
+
+
+/* use Pivoted Cholesky to efficiently select an optimal subset
+   of available build points from which to construct the Gaussian
+   Process.  Here "optimal" means that, given the current set of
+   assumed correlation parameters, this subset maximizes the
+   amount of unique information content in R, note that this is
+   equivalent to a "best spaced" (for the chosen correlation
+   function and its parameters) set of points and the output at
+   those points does is not considered.  Thus if you have 2 points
+   that are very close together but on opposite sides of a
+   discontinutity it is highly likely that at least one of them
+   will get discarded */
+void KrigingModel::equationSelectingCholR(){
+  if(!((buildDerOrder==0)||(buildDerOrder==1))) {
+    std::cerr << "buildDerOrder=" << buildDerOrder
+	      << " in void KrigingModel::equationSelectingCholR().  "
+	      << "For Kriging buildDerOrder must equal 0.  "
+	      << "For Gradient Enhanced Kriging (GEK) buildDerOrder "
+	      << "must equal 1.  Higher order derivative enhanced "
+	      << "Kriging (e.g. Hessian Enhanced Kriging) has not "
+	      << "been implemented." << std::endl;
+    assert(false);
+  }
+
+  //polyOrder=polyOrderRequested;
+  nTrend=numTrend(polyOrderRequested,0);
+  Rinv_Gtran.newSize(numEqnAvail,nTrend);
+
+
+  //printf("Entered equationSelectingCholR()\n");
+  double min_allowed_rcond=1.0/maxCondNum;
+  //printf("min_allowed_rcond=%g\n",min_allowed_rcond);
+  //exit(0);
+  //double min_allowed_pivot_est_rcond=256.0/maxCondNum;
+
+  int ld_RChol=RChol.getNRowsAct();
+  //printf("ld_RChol=%d\n",ld_RChol);
+  int chol_info;
+  RChol.newSize(numPoints,numPoints);
+  scaleRChol.newSize(numEqnAvail,3); //maximum space needed
+  rcondDblWork.newSize(3*ld_RChol,1);
+  rcondIntWork.newSize(ld_RChol,1);
+  ld_RChol=RChol.getNRowsAct();
+
+  iPtsKeep.newSize(numPoints,1);
+  //assign the default order to points
+  for(int ipt=0; ipt<numPoints; ++ipt)
+    iPtsKeep(ipt,0)=ipt;
+
+  if(buildDerOrder==0) {
+    //We're using regular Kriging not GEK and for large matrices
+    //the pivoted Cholesky algorithm is nowhere close to as fast
+    //as the highly optimized level 3 LAPACK Cholesky so to make
+    //this run faster on average we're going to attempt to use
+    //the LAPACK cholesky take a look at the rcondR and then only
+    //do Pivoted Cholesky if we actually need to
+    RChol.copy(R);
+
+    //no scaling is necessary since have all ones on the diagonal
+    //of the Kriging R but the generic equilibrated Cholesky
+    //factoriztion function doesn't know that in advance
+    Chol_fact_workspace(RChol,scaleRChol,rcondDblWork,rcondIntWork,
+			chol_info,rcondR);
+    if(min_allowed_rcond<rcondR) {
+      numRowsR=numWholePointsKeep=numPointsKeep=numPoints;
+
+      Y.copy(Yall);
+
+      nTrend=numTrend(polyOrderRequested,0);
+      Gtran.newSize(numPoints,nTrend);
+      for(int itrend=0; itrend<nTrend; ++itrend)
+	for(int ipt=0; ipt<numPoints; ++ipt)
+	  Gtran(ipt,itrend)=Gall(itrend,ipt);
+
+      return;
+    }
+  }
+
+  // *******************************************************************
+  // in this section I need to get an optimally reordered Cholesky
+  // factorization of the Kriging or GEK R matrix and I need to compute
+  // the one norm for all sizes of that optimally reordered R matrix
+  // *******************************************************************
+  // We got here in one of two ways
+  //
+  // 1) We're doing Kriging and we actually need to do Pivoted Cholesky
+  //
+  // 2) We're doing Gradient Enhanced Kriging, and reordering "whole
+  //    points" (function value immediately followed by its derivatives)
+  //    according to the order of the Pivoted Cholesky on the Kriging R
+  //    works a lot better and is a lot faster than doing Pivoted
+  //    Cholesky on the GEK R.  In fact because the GEK R is so much
+  //    larger than the Kriging R, the cost of doing pivoted Cholesky on
+  //    the Kriging R will be insignificant compared to the cost of
+  //    doing LAPACK Cholesky on the GEK R so I'm just going to go ahead
+  //    and reorder the GEK R whether I need to or not (which I don't
+  //    know at this point anyway) rather than risk having to do the
+  //    LAPACK Cholesky twice
+
+  //if the user specifies an anchor point it must be the first point to
+  //prevent it from being pivoted away
+  if(ifHaveAnchorPoint&&(iAnchorPoint!=0)) {
+    iPtsKeep(iAnchorPoint,0)=0;
+    iPtsKeep(0,0)=iAnchorPoint;
+  }
+  else iAnchorPoint=0;
+
+  for(int jpt=0; jpt<numPoints; ++jpt) {
+    int jsrc=iPtsKeep(jpt,0);
+    for(int ipt=0; ipt<numPoints; ++ipt)
+      RChol(ipt,jpt)=R(iPtsKeep(ipt,0),jsrc);
+  }
+
+  int info=0;
+  char uplo='B'; //'B' means we have both halves of R in RChol so the
+  //fortran doesn't have to copy one half to the other, having both
+  //halves makes the memory access faster (can always go down columns)
+  numPointsKeep=numPoints;
+  PIVOTCHOL_F77(&uplo, &numPoints, RChol.ptr(0,0), &ld_RChol,
+    		iPtsKeep.ptr(0,0), &numPointsKeep, &min_allowed_rcond,
+		&info);
+
+  //for(int ipt=0; ipt<numPoints; ++ipt)
+  //printf("F77 iPtsKeep(%d)=%d\n",ipt,iPtsKeep(ipt,0));
+  //printf("\n");
+
+  //printf("*********************************\n");
+
+  if(ifHaveAnchorPoint&&(iAnchorPoint!=0)) {
+    iPtsKeep(0,0)=iAnchorPoint;
+    for(int ipt=1; ipt<numPoints; ++ipt) {
+      iPtsKeep(ipt,0)-=1; //Fortran indices start at 1 not zero so
+      //we have to convert to C++ indices which start from 0
+      if(iPtsKeep(ipt,0)==iAnchorPoint)
+	iPtsKeep(ipt,0)=0;
+    }
+  }
+  else {
+    for(int ipt=0; ipt<numPoints; ++ipt) {
+      iPtsKeep(ipt,0)-=1; //Fortran indices start at 1 not zero so
+      //we have to convert to C++ indices which start from 0
+      //printf("iPtsKeep(%2d,0)=%d\n",ipt,iPtsKeep(ipt,0));
+    }
+    //printf("\n");
+  }
+
+  //if I feed LAPACK a one norm of R and a Cholesky factorization of
+  //R it will give me back an rcond for O(N^2) ops which is practically
+  //free compared to the O(N^3) ops that the Cholesky factorization
+  //costs, the wonderful thing is if I just drop equations off the end
+  //of a pivoted Cholesky factorization I can get the rcondR for any
+  //number of rows/columns of the pivoted R matrix, but to make this
+  //efficient I need to get the one norms of R cheaply (easily doable,
+  //that's what happens in the next if Kriging els if GEK statement)
+  //and I'll use bisection to find the last equation I can retain
+  int iprev_lapack_rcondR;
+  int icurr_lapack_rcondR=numEqnAvail-1;
+  int num_eqn_keep=numEqnAvail;
+  oneNormR.newSize(numEqnAvail,1);
+  sumAbsColR.newSize(numEqnAvail,1);
+  if(buildDerOrder==0) {
+    //Kriging we need to compute the one-norms for the reordered Kriging
+    //R matrix
+    //the one norm is the largest of the sums of the absolute value of
+    //any of the columns, of course how many rows there are affects what
+    //the sums of absolute value of the columns are and how many columns
+    //there are affects which is the largest but we can build this up in
+    //such a way as to reuse the information from smaller numbers of
+    //rows/columns for larger numbers of rows/columns
+
+    int jsrc=iPtsKeep(0,0);
+    for(int ipt=0; ipt<numPoints; ++ipt)
+      sumAbsColR(ipt,0)=std::fabs(R(iPtsKeep(ipt,0),jsrc));
+    oneNormR(0,0)=sumAbsColR(0,0); //this is the one norm for the 1 by
+    //1 reordered R matrix
+
+    double tempdouble;
+    for(int jpt=1; jpt<numPoints; ++jpt) {
+      jsrc=iPtsKeep(jpt,0);
+      for(int ipt=0; ipt<numPoints; ++ipt)
+	sumAbsColR(ipt,0)+=std::fabs(R(iPtsKeep(ipt,0),jsrc));
+      tempdouble=sumAbsColR(0,0);
+      for(int ipt=1; ipt<=jpt; ++ipt)
+	if(tempdouble<sumAbsColR(ipt,0))
+	  tempdouble=sumAbsColR(ipt,0);
+      oneNormR(jpt,0)=tempdouble; //this is the one norm for the
+      //jpt by jpt reordered R matrix
+    }
+    uplo='L'; //get it into the same state as GEK
+    iprev_lapack_rcondR=0; //a 1 by 1 matrix has a condition number of 1
+
+  } else if(buildDerOrder==1){
+    //Gradient Enhanced Kriging
+    //it works better (and is a lot faster) if we reorder whole points
+    //according to the Pivoted Cholesky ON THE KRIGING R order in iPtsKeep
+    //so we'll calculate the one norm for all sizes of the reordered
+    //GEK R and then Cholesky factorize the GEK R
+    reorderCopyRtoRChol();
+    /*
+    printf("R=\n");
+    for(int i=0; i<numEqnAvail; ++i) {
+      for(int j=0; j<numEqnAvail; ++j)
+	printf("%14.8g ",RChol(i,j));
+      printf("\n");
+    }
+    printf("\n");
+    */
+    scaleRChol.newSize(numEqnAvail,2);
+    for(int i=0; i<numEqnAvail; ++i) {
+      scaleRChol(i,1)=std::sqrt(RChol(i,i));
+      scaleRChol(i,0)=1.0/scaleRChol(i,1);
+    }
+
+    //equilibrate RChol
+    for(int j=0; j<numEqnAvail; ++j) {
+      for(int i=0; i<numEqnAvail; ++i)
+	RChol(i,j)*=scaleRChol(i,0)*scaleRChol(j,0);
+      RChol(j,j)=1.0; //there is zero correlation between an individual
+      //point's function value and its derivatives so we know how to fix
+      //round of error so just do it
+    }
+    /*
+    printf("RE=\n");
+    for(int i=0; i<numEqnAvail; ++i) {
+      for(int j=0; j<numEqnAvail; ++j)
+	printf("%14.8g ",RChol(i,j));
+      printf("\n");
+    }
+    printf("\n");
+    */
+    //the one norm number is the largest of the sums of the absolute
+    //value of any of the columns of the matrix, of course how many rows
+    //there are affects what the sums of absolute value of the columns
+    //are and how many columns there are affects which is the largest
+    //but we can build this up in such a way as to reuse the information
+    //from smaller numbers of rows/columns for larger numbers of rows/
+    //columns
+
+    //right now RChol holds the reordered R matrix
+    for(int i=0; i<numEqnAvail; ++i)
+      sumAbsColR(i,0)=std::fabs(RChol(i,0));
+    oneNormR(0,0)=sumAbsColR(0,0); //this is the one norm for the 1 by
+    //1 reordered R matrix
+
+    double tempdouble;
+    for(int j=1; j<numEqnAvail; ++j) {
+      for(int i=0; i<numEqnAvail; ++i)
+	sumAbsColR(i,0)+=std::fabs(RChol(i,j));
+      tempdouble=sumAbsColR(0,0);
+      for(int i=1; i<=j; ++i)
+	if(tempdouble<sumAbsColR(i,0))
+	  tempdouble=sumAbsColR(i,0);
+      oneNormR(j,0)=tempdouble;  //this is the one norm for the
+      //j by j reordered R matrix
+    }
+
+    //do the (highly optimized) LAPACK Cholesky Decomposition of all
+    //the equations (but sorted into the point order determined by
+    //the pivoting cholesky above)
+    uplo='L';
+    DPOTRF_F77(&uplo,&numEqnAvail,RChol.ptr(0,0),&ld_RChol,&info);
+
+    //Kriging already has the rcondR so to get GEK into an equivalent
+    //state we will feed LAPACK the one norm of the full GEK R (after
+    //the reordering and equilibration) and it will give me back GEK's
+    //rcondR
+    DPOCON_F77(&uplo,&numEqnAvail,RChol.ptr(0,0),&ld_RChol,
+	       oneNormR.ptr(icurr_lapack_rcondR,0),
+	       &rcondR,rcondDblWork.ptr(0,0),rcondIntWork.ptr(0,0),
+	       &info);
+
+    //printf("rcond(RE)=%g icurr_lapack_rcondR=%d\n",rcondR,icurr_lapack_rcondR);
+
+    //the first derivatives of the correlation at a point are uncorrelated
+    //with the correlation function at the same point, i.e. the (1+numVarsr)
+    //by (1+numVarsr) correlation matrix has a condition number of 1
+    iprev_lapack_rcondR=numVarsr; //no 1+ because C++ indexes start at zero
+  }
+
+  // *****************************************************************
+  // in this section we will efficiently determine the maximum number
+  // of equations that we can retain by doing a bisection search using
+  // O(log2(N)) calls of LAPACK's rcond estimate (each of which cost
+  // only O(n^2) ops where n is the number of eqns in the current
+  // subset
+  // *****************************************************************
+
+  lapackRcondR.newSize(numEqnAvail,1);
+  lapackRcondR(iprev_lapack_rcondR,0)=1.0; //since the condition number
+  //is one at iprev_lapack_rcondR we know we can keep at least this many
+  //equations
+
+  lapackRcondR(icurr_lapack_rcondR,0)=rcondR; //the maximum number
+  //of equations we can keep is icurr_lapack_rcondR=numEqnAvail-1
+  //and we know the rcondR for that many equations
+
+  //note num_eqn_keep is now numEqnAvail
+  int inext_lapack_rcondR=icurr_lapack_rcondR; //the last available eqn
+  if((rcondR<=min_allowed_rcond)&&
+     (inext_lapack_rcondR-iprev_lapack_rcondR==1)) {
+    //at this point the previous lapack rcondR==1.0
+    rcondR=1.0;
+    inext_lapack_rcondR=iprev_lapack_rcondR;
+    //printf("if1\n");
+  }
+
+  //do the bisection search if necessary, at most ceil(log2()) more
+  //calls to the LAPACK rcond function
+  int rcond_iter=0;
+  int max_rcond_iter=
+    std::ceil(std::log(static_cast<double>
+		       (inext_lapack_rcondR-iprev_lapack_rcondR))
+	      /std::log(2.0));
+  while((lapackRcondR(inext_lapack_rcondR,0)<=min_allowed_rcond)&&
+        (inext_lapack_rcondR>iprev_lapack_rcondR)) {
+    //printf("inWhile\n");
+    ++rcond_iter;
+    icurr_lapack_rcondR=(iprev_lapack_rcondR+inext_lapack_rcondR)/2;
+    num_eqn_keep=icurr_lapack_rcondR+1;
+
+    //the LAPACK rcond function
+    DPOCON_F77(&uplo,&num_eqn_keep,RChol.ptr(0,0),&ld_RChol,
+	       oneNormR.ptr(icurr_lapack_rcondR,0),
+	       &rcondR,rcondDblWork.ptr(0,0),rcondIntWork.ptr(0,0),
+	       &info);
+    lapackRcondR(icurr_lapack_rcondR,0)=rcondR;
+    //printf("rcond_iter=%d icurr_lapack_rcondR=%d rcondR=%g\n",
+    //rcond_iter,icurr_lapack_rcondR,rcondR);
+
+    if(rcondR<min_allowed_rcond)
+      inext_lapack_rcondR=icurr_lapack_rcondR;
+    else if(min_allowed_rcond<rcondR)
+      iprev_lapack_rcondR=icurr_lapack_rcondR;
+    else if(min_allowed_rcond==rcondR) {
+      //num_eqn_keep=icurr_lapack_rcondR+1;
+      break;
+    }
+    if((inext_lapack_rcondR-iprev_lapack_rcondR==1)||
+       (max_rcond_iter<rcond_iter)) {
+      num_eqn_keep=iprev_lapack_rcondR+1;
+      rcondR=lapackRcondR(iprev_lapack_rcondR,0);
+      break;
+    }
+  }
+  //printf(" pivoted_rcondR=%g numRowsR=%d\n",rcondR,num_eqn_keep);
+
+  numRowsR=num_eqn_keep; //this is the maximum number of equations that
+  //we can keep
+
+  // ***************************************************************
+  // in this section we downsize the arrays being retained and keep
+  // only the optimal subset, in or working copies
+  // ***************************************************************
+
+  RChol.resize(num_eqn_keep,num_eqn_keep); //resize() instead of newSize()
+  //because we want to keep the current contents in the same 2D
+  //order
+  /*
+  if(num_eqn_keep>=10) {
+    printf("RChol(1:10,1:10)=\n");
+    for(int i=0; i<10; ++i) {
+      for(int j=0; j<10; ++j)
+	printf("%12.6g ",RChol(i,j));
+      printf("\n");
+    }
+    printf("\n\n");
+  }
+  */
+
+  //polyOrder=polyOrderRequested; //redundant but for clarity
+
+  //the following while loop was commented out when adaptive selection of
+  //the trend basis functions via pivote cholesky factorization of G*R^-1*G^T
+  //was implemented
+  //while((numRowsR<=numTrend(polyOrder,0))&&(polyOrder>0))
+  //--polyOrder;
+
+  //nTrend=numTrend(polyOrder,0); //commented out because we now select a subset of Poly based using a Pivoted Cholesky factorization of G*R^-1*G^T which happens when trendSelectingPivotedCholesy is called by materObjectiveAndConstraints() (we no longer select SOLELY on polynomial order and number of points
+
+  nTrend=numTrend(polyOrderRequested,0);
+
+  //printf("num_eqn_keep=%d numRowsR=%d polyOrder=%d nTrend=%d rcondR=%g lapackRcondR(num_eqn_keep-1,0)=%g\n",num_eqn_keep,numRowsR,polyOrder,nTrend,rcondR,lapackRcondR(num_eqn_keep-1,0));
+
+  //we need to downsize Gtran now but we only need to downsize Poly at
+  //the end of create()
+  Gtran.newSize(num_eqn_keep,nTrend); //newSize() because we don't care
+ //about the current contents of Gtran
+
+  Y.newSize(num_eqn_keep,1); //newSize() because we don't care about
+  //the current contents of Y
+
+  if(buildDerOrder==0) {
+    // keep only the useful parts for Kriging
+    numWholePointsKeep=numPointsKeep=num_eqn_keep;
+    numExtraDerKeep=0;
+
+    /*
+    if(numPointsKeep>10) {
+
+      MtxDbl RCholDEBUG(numPointsKeep,numPointsKeep);
+      for(int jpt=0; jpt<numPointsKeep; ++jpt) {
+	int jsrc=iPtsKeep(jpt,0);
+	for(int ipt=0; ipt<numPointsKeep; ++ipt)
+	  RCholDEBUG(ipt,jpt)=R(iPtsKeep(ipt,0),jsrc);
+      }
+      double rcondRDEBUG;
+      int chol_info_debug;
+
+      printf("Rreorder(1:10,1:10)=\n");
+      for(int ipt=0; ipt<10; ++ipt) {
+	for(int jpt=0; jpt<10; ++jpt)
+	  printf("%12.6g ",RCholDEBUG(ipt,jpt));
+	printf("\n");
+      }
+      printf("\n\n");
+
+      Chol_fact_workspace(RCholDEBUG,scaleRChol,rcondDblWork,rcondIntWork,
+			  chol_info_debug,rcondRDEBUG);
+
+      printf("RChol(1:10,1:10)=\n");
+      for(int ipt=0; ipt<10; ++ipt) {
+	for(int jpt=0; jpt<10; ++jpt)
+	  printf("%12.6g ",RChol(ipt,jpt));
+	printf("\n");
+      }
+      printf("\n\n");
+
+      printf("RCholDEBUG(1:10,1:10)=\n");
+      for(int ipt=0; ipt<10; ++ipt) {
+	for(int jpt=0; jpt<10; ++jpt)
+	  printf("%12.6g ",RCholDEBUG(ipt,jpt));
+	printf("\n");
+      }
+      printf("\n\n");
+
+      printf("[RChol-RCholDEBUG](1:10,1:10)=\n");
+      for(int ipt=0; ipt<10; ++ipt) {
+	for(int jpt=0; jpt<10; ++jpt)
+	  printf("%12.6g ",RChol(ipt,jpt)-RCholDEBUG(ipt,jpt));
+	printf("\n");
+      }
+      printf("\n\n");
+
+      printf("rcondR=%g rcondRDEBUG=%g numPointsKeep=%d\nErrorRChol=\n",
+	     rcondR,rcondRDEBUG,numPointsKeep);
+
+    }
+    */
+
+    //keep the useful part of Y
+    for(int ipt=0; ipt<numPointsKeep; ++ipt)
+      Y(ipt,0)=Yall(iPtsKeep(ipt,0),0);
+
+    //keep the useful part of G (actually G^T)
+    for(int itrend=0; itrend<nTrend; ++itrend)
+      for(int ipt=0; ipt<numPointsKeep; ++ipt)
+	Gtran(ipt,itrend)=Gall(itrend,iPtsKeep(ipt,0));
+
+    /*
+    for(int ipt=0; ipt<numPointsKeep; ++ipt) {
+      printf("Gtran(%3d,:)=[%12.6g",ipt,Gtran(ipt,0));
+      for(int itrend=1; itrend<nTrend; ++itrend)
+	printf(", %12.6g",Gtran(ipt,itrend));
+      printf("] XR(:,%3d)=[%12.6g",ipt,XR(0,iPtsKeep(ipt,0)));
+      for(int k=1; k<numVarsr; ++k)
+	printf(", %12.6g",XR(k,iPtsKeep(ipt,0)));
+      printf("]^T Y(%3d,0)=%12.6g\n",ipt,Y(ipt,0));
+    }
+    printf("\n");
+    */
+
+
+  } else if(buildDerOrder==1) {
+    // keep on the useful parts for Gradient Ehanced Kriging
+
+    //integer division automatically rounds down
+    numWholePointsKeep=num_eqn_keep/(1+numVarsr);
+
+    //we also need to round up
+    numPointsKeep=
+      static_cast<int>(std::ceil(static_cast<double>(num_eqn_keep)/
+				 static_cast<double>(1+numVarsr)));
+
+    if(numPointsKeep==numWholePointsKeep) {
+      //perhaps a better name would be numLastDerKeep... this is the number
+      //of derivatives retained for the last point.
+      numExtraDerKeep==numVarsr;
+    } else
+      numExtraDerKeep=num_eqn_keep-(1+numWholePointsKeep*(1+numVarsr));
+
+    //we need to undo the equilibration of RChol, recall that scaleRChol
+    //is already in the pivoted Cholesky order
+    for(int j=0; j<num_eqn_keep; ++j)
+      for(int i=j; i<num_eqn_keep; ++i)
+	RChol(i,j)*=scaleRChol(i,1); //note that this assumes that the
+    //nkm::SurfMat class uses the lower triangular part of of RChol
+    //otherwise (if this function uses the lower triangular part but
+    //surfmat uses the upper triangular part) you'd need
+    //RChol(j,i)=RChol(i,j)*scaleRChol(i,j) but you could do a
+    //RChol(j,i)=RChol(i,j)*=ScaleRChol(i,1); just to be safe
+
+    //keep the useful part of G (actually G^T)
+    for(int itrend=0; itrend<nTrend; ++itrend) {
+      int i, ipt;
+      for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt) {
+	int isrc=iPtsKeep(ipt,0)*(1+numVarsr);
+	for(int k=0; k<1+numVarsr; ++k, ++isrc, ++i)
+	  Gtran(i,itrend)=Gall(itrend,isrc);
+      }
+      if(numPointsKeep>numWholePointsKeep) {
+#ifdef __KRIG_ERR_CHECK__
+	assert((ipt==numWholePointsKeep)&&
+	       (i==(numWholePointsKeep*(1+numVarsr)))&&
+	       (numWholePointsKeep+1==numPointsKeep));
+#endif
+	int isrc=iPtsKeep(ipt,0)*(1+numVarsr);
+	Gtran(i,itrend)=Gall(itrend,isrc);
+	++i;
+	++isrc;
+	for(int k=0; k<numExtraDerKeep; ++k, ++isrc, ++i)
+	  Gtran(i,itrend)=Gall(itrend,isrc);
+      }
+    }
+
+    //keep the useful part of Y, also we need to undo the
+    //equilibration of RChol
+    { //{ to impose scope
+      int i, ipt;
+      for(ipt=0, i=0; ipt<numWholePointsKeep; ++ipt) {
+	int isrc=iPtsKeep(ipt,0)*(1+numVarsr);
+	for(int k=0; k<1+numVarsr; ++k, ++isrc, ++i)
+	  Y(i,0)=Yall(isrc,0);
+      }
+      if(numPointsKeep>numWholePointsKeep) {
+#ifdef __KRIG_ERR_CHECK__
+	assert((ipt==numWholePointsKeep)&&
+	       (i==(numWholePointsKeep*(1+numVarsr)))&&
+	       (numWholePointsKeep+1==numPointsKeep));
+#endif
+	int isrc=iPtsKeep(ipt,0)*(1+numVarsr);
+	Y(i,0)=Yall(isrc,0);
+	++i;
+	++isrc;
+	for(int k=0; k<numExtraDerKeep; ++k, ++isrc, ++i)
+	  Y(i,0)=Yall(isrc,0);
+      }
+    } //{} to impose scope
+  } //else if(buildDerOrder==1) {
+
+  iPtsKeep.resize(numPointsKeep,1);
+
+  return;
+}
+
+/** G_Rinv_Gtran must be filled with G*R^-1*G^T prior to calling
+    void KrigingModel::trendSelectingPivotedCholesky() */
+void KrigingModel::trendSelectingPivotedCholesky(){
+
+  //nTrend=numTrend(polyOrderRequested,0);
+  iTrendKeep.newSize(nTrend,1);
+  double min_allowed_rcond=1.0/maxCondNum;
+  int num_trend_want=numTrend(polyOrderRequested,0);
+
+  int max_trend_to_keep=numRowsR-1-2*numVarsr;
+  if(numRowsR/2<max_trend_to_keep)
+    max_trend_to_keep=numRowsR/2;
+  if(num_trend_want<max_trend_to_keep)
+    max_trend_to_keep=num_trend_want;
+  if(max_trend_to_keep<1)
+    max_trend_to_keep=1;
+
+  //std::cout << "numRowrR=" << numRowsR << " nTrend=" << nTrend << " max_trend_to_keep=" << max_trend_to_keep << std::endl;
+
+  if(nTrend<=max_trend_to_keep) {
+    //do a LAPACK cholesky first
+    G_Rinv_Gtran_Chol.copy(G_Rinv_Gtran);
+    int chol_info;
+    Chol_fact_workspace(G_Rinv_Gtran_Chol,G_Rinv_Gtran_Chol_Scale,
+			G_Rinv_Gtran_Chol_DblWork,G_Rinv_Gtran_Chol_IntWork,
+			chol_info,rcond_G_Rinv_Gtran);
+    if(min_allowed_rcond<rcond_G_Rinv_Gtran) {
+      //the LAPACK Cholesky was not ill-conditioned with the desired
+      //full set of trend basis functions so we'll use them all
+      for(int itrend=0; itrend<nTrend; ++itrend)
+	iTrendKeep(itrend,0)=itrend;
+      return;
+    }
+  }
+
+  // *****************************************************************
+  // if we got here we need to do a Pivoted Cholesky factorization of
+  // G*R^-1*G^T to select an optimal subset of trend basis functions
+  // *****************************************************************
+
+  // we have a slight problem, basically the one trend function that
+  // is guaranteed to be selected is the one that has the largest
+  // diagonal element in G*R^-1*G^T, or if they are all the same it
+  // will be the first one.  we want to guarantee that the constant
+  // basis function (polynomial of order 0) is retained so we need to
+  // equilibrate G_Rinv_Gtran so that it has all ones on the diagonal
+  // and therefore that the constant trend basis function will be
+  // retained
+
+  // I realize this has R in the name but I don't want to allocate another
+  // variable
+  scaleRChol.newSize(nTrend,3);
+  for(int itrend=0; itrend<nTrend; ++itrend) {
+    scaleRChol(itrend,1)=std::sqrt(G_Rinv_Gtran(itrend,itrend));
+    scaleRChol(itrend,0)=1.0/scaleRChol(itrend,1);
+  }
+
+
+  for(int jtrend=0; jtrend<nTrend; ++jtrend) {
+    double tempdouble=scaleRChol(jtrend,0);
+    for(int itrend=0; itrend<nTrend; ++itrend)
+      G_Rinv_Gtran(itrend,jtrend)*=scaleRChol(itrend,0)*tempdouble;
+    G_Rinv_Gtran(jtrend,jtrend)=1.0; //numerical round off error could
+    //kill our guarantee of keeping the constant trend basis function
+    //so we'll just assign the right correct answer which is 1.0
+  }
+
+  G_Rinv_Gtran_Chol.copy(G_Rinv_Gtran);
+
+  int ld_G_Rinv_Gtran_Chol=G_Rinv_Gtran_Chol.getNRowsAct();
+  int info=0;
+  char uplo='B'; //'B' means we have both halves of G*R^-1*G^T in
+  //G_Rinv_Gtran_Chol so the FORTRAN doesn't have to copy one half to the
+  //other, having both halves makes the memory access faster (can always
+  //go down columns)
+  int num_trend_keep=-max_trend_to_keep; //RANK<0 on input tells PIVOTCHOL_F77
+  //that we only want to keep the first abs(RANK) entries so it can stop early
+  PIVOTCHOL_F77(&uplo, &nTrend, G_Rinv_Gtran_Chol.ptr(0,0),
+		&ld_G_Rinv_Gtran_Chol, iTrendKeep.ptr(0,0), &num_trend_keep,
+		&min_allowed_rcond, &info);
+
+  nTrend=num_trend_keep; //this is the maximum number of trend functions
+  //we could keep, we might not be able to keep this many
+
+  //FORTRAN indices start at 1 not zero so we have to convert to C++ indices
+  //which start at zero
+  for(int itrend=0; itrend<nTrend; ++itrend)
+    iTrendKeep(itrend,0)-=1;
+
+  // ************************************************************
+  // in this section I need to calculate the one norm for subsets
+  // of the first jtrend (reordered) rows/columns of the
+  // equilibrated G*R^-1*G^T , for jtrend=1 to nTrend
+  // ************************************************************
+
+  //I realize that this says R but I don't want to allocate another variable
+  oneNormR.newSize(nTrend,1);
+  //I realize that this says R but I don't want to allocate another variable
+  sumAbsColR.newSize(nTrend,1);
+  int jsrc=iTrendKeep(0,0);
+  for(int itrend=0; itrend<nTrend; ++itrend)
+    sumAbsColR(itrend,0)=std::fabs(G_Rinv_Gtran(iTrendKeep(itrend,0),jsrc));
+  oneNormR(0,0)=sumAbsColR(0,0); //this is the one norm for the 1 by
+  //1 reordered G_Rinv_Gtran matrix
+
+  double tempdouble;
+  for(int jtrend=1; jtrend<nTrend; ++jtrend) {
+    jsrc=iTrendKeep(jtrend,0);
+    for(int itrend=0; itrend<nTrend; ++itrend)
+      sumAbsColR(itrend,0)+=std::fabs(G_Rinv_Gtran(iTrendKeep(itrend,0),jsrc));
+    tempdouble=sumAbsColR(0,0);
+    for(int itrend=1; itrend<=jtrend; ++itrend)
+      if(tempdouble<sumAbsColR(itrend,0))
+	tempdouble=sumAbsColR(itrend,0);
+    oneNormR(jtrend,0)=tempdouble; //this is the one norm for the
+    //jtrend by jtrend reordered G_Rinv_Gtran matrix
+  }
+
+  ld_G_Rinv_Gtran_Chol=G_Rinv_Gtran_Chol.getNRowsAct(); //this probably hasn't changed
+  //but better safe than sorry
+  rcondDblWork.newSize(3*ld_G_Rinv_Gtran_Chol,1);
+  rcondIntWork.newSize(ld_G_Rinv_Gtran_Chol,1);
+  int icurr_lapack_rcond=nTrend-1;
+  uplo='L';
+  DPOCON_F77(&uplo,&nTrend,G_Rinv_Gtran_Chol.ptr(0,0),&ld_G_Rinv_Gtran_Chol,
+	     oneNormR.ptr(icurr_lapack_rcond,0),&rcond_G_Rinv_Gtran,
+	     rcondDblWork.ptr(0,0),rcondIntWork.ptr(0,0),&info);
+
+  //need to do a bisection search for the last trend function that we can keep
+  lapackRcondR(icurr_lapack_rcond,0)=rcond_G_Rinv_Gtran; //the maximum number
+  //of trend basis functions we can keep is icurr_lapack_rcond=nTrend-1
+  //and we know the rcond for that many equations
+  int iprev_lapack_rcond=0;
+  lapackRcondR(iprev_lapack_rcond,0)=1.0; //the constant trend funcation by
+  //itself is guaranteed to have condition # = 1.0
+
+  //note num_trend_keep is now nTrend
+  int inext_lapack_rcond=icurr_lapack_rcond; //the last available basis
+  //function
+  if((rcond_G_Rinv_Gtran<=min_allowed_rcond)&&
+     (inext_lapack_rcond-iprev_lapack_rcond==1)) {
+    //at this point the previous lapack rcondR==1.0
+    rcond_G_Rinv_Gtran=1.0;
+    inext_lapack_rcond=iprev_lapack_rcond;
+    //printf("if1\n");
+  }
+
+  //do the bisection search if necessary, at most ceil(log2()) more
+  //calls to the LAPACK rcond function
+  int rcond_iter=0;
+  int max_rcond_iter=
+    std::ceil(std::log(static_cast<double>
+		       (inext_lapack_rcond-iprev_lapack_rcond))
+	      /std::log(2.0));
+  while((lapackRcondR(inext_lapack_rcond,0)<=min_allowed_rcond)&&
+        (inext_lapack_rcond>iprev_lapack_rcond)) {
+    //printf("inWhile\n");
+    ++rcond_iter;
+    icurr_lapack_rcond=(iprev_lapack_rcond+inext_lapack_rcond)/2;
+    num_trend_keep=icurr_lapack_rcond+1;
+
+    //the LAPACK rcond function
+    DPOCON_F77(&uplo,&num_trend_keep,G_Rinv_Gtran_Chol.ptr(0,0),
+	       &ld_G_Rinv_Gtran_Chol,oneNormR.ptr(icurr_lapack_rcond,0),
+	       &rcond_G_Rinv_Gtran,rcondDblWork.ptr(0,0),
+	       rcondIntWork.ptr(0,0),&info);
+    lapackRcondR(icurr_lapack_rcond,0)=rcond_G_Rinv_Gtran;
+    //printf("rcond_iter=%d icurr_lapack_rcondR=%d rcondR=%g\n",
+    //rcond_iter,icurr_lapack_rcondR,rcondR);
+
+    if(rcond_G_Rinv_Gtran<min_allowed_rcond)
+      inext_lapack_rcond=icurr_lapack_rcond;
+    else if(min_allowed_rcond<rcond_G_Rinv_Gtran)
+      iprev_lapack_rcond=icurr_lapack_rcond;
+    else if(min_allowed_rcond==rcond_G_Rinv_Gtran) {
+      //num_trend_keep=icurr_lapack_rcond+1;
+      break;
+    }
+    if((inext_lapack_rcond-iprev_lapack_rcond==1)||
+       (max_rcond_iter<rcond_iter)) {
+      num_trend_keep=iprev_lapack_rcond+1;
+      rcond_G_Rinv_Gtran=lapackRcondR(iprev_lapack_rcond,0);
+      break;
+    }
+  }
+  //printf(" pivoted_rcondR=%g numRowsR=%d\n",rcondR,num_eqn_keep);
+
+  nTrend=num_trend_keep; //this is the maximum number of trend basis functions
+  //that we can keep
+
+  iTrendKeep.resize(nTrend,1);
+  //we don't want the basis functions in their optimal order we want them
+  //in their logical order, minus the ones we couldn't keep
+  iTrendKeep.sortRows();
+
+  //were going to copy the portion of the equilibrated G*R^-1*G^T matrix
+  //that were keeping, in its logical order, into G_Rinv_Gtran_Chol and then
+  //do a LAPACK cholesky on it, and then undo the equilibration
+  G_Rinv_Gtran_Chol.newSize(nTrend,nTrend);
+  for(int jtrend=0; jtrend<nTrend; ++jtrend) {
+    int jsrc=iTrendKeep(jtrend,0);
+    scaleRChol(jtrend,2)=scaleRChol(jsrc,1);
+    for(int itrend=0; itrend<nTrend; ++itrend)
+      G_Rinv_Gtran_Chol(itrend,jtrend)=G_Rinv_Gtran(iTrendKeep(itrend,0),jsrc);
+  }
+
+  //do the LAPACK cholesky factorization
+  int chol_info;
+  Chol_fact_workspace(G_Rinv_Gtran_Chol,G_Rinv_Gtran_Chol_Scale,
+		      G_Rinv_Gtran_Chol_DblWork,G_Rinv_Gtran_Chol_IntWork,
+		      chol_info,rcond_G_Rinv_Gtran);
+
+  //we still need to undo the equilbration because we copied the
+  //equilibrated G*R^-1*G^T matrix into G_Rinv_Gtran_Chol before doing
+  //the cholesky factorization
+  for(int jtrend=0; jtrend<nTrend; ++jtrend)
+    for(int itrend=jtrend; itrend<nTrend; ++itrend)
+      G_Rinv_Gtran_Chol(itrend,jtrend)*=scaleRChol(itrend,2);
+
+
+
+  for(int itrend=1; itrend<nTrend; ++itrend) {
+    int isrc=iTrendKeep(itrend,0);
+    if(itrend<isrc)
+      for(int i=0; i<numRowsR; ++i) {
+	Gtran(i,itrend)=Gtran(i,isrc);
+	Rinv_Gtran(i,itrend)=Rinv_Gtran(i,isrc);
+      }
+  }
+  Gtran.resize(numRowsR,nTrend);
+  Rinv_Gtran.resize(numRowsR,nTrend);
+
+  //and were done with the pivoted cholesky, but at the end of the optimization
+  //we will still need to discard the subset of Poly that was not selected by
+  //trendSelectingPivotedCholesky()
+  return;
+}
+
+
+
+
+
+/** this function calculates the objective function (negative "per equation"
+    log likelihood) and/or the constraint (reciprocal condition number)
+    functions using a precompute and store (store across sequential calls
+    to this function) strategy to reduce the computational cost, make sure
+    only to COPY OUT results from member variables so the state is not
+    changed
+*/
+void KrigingModel::masterObjectiveAndConstraints(const MtxDbl& theta, int obj_der_mode, int con_der_mode)
+{
+  // if(obj_der_mode=1) (1=2^0=> 0th derivative) calculate objective function
+  // if(con_der_mode=1) (1=2^0=> 0th derivative) calculate the constraint
+  //functions
+  // ERROR if(con_der_mode>=2) (2=2^1 = 1st derivative) this function does not
+  //                           support analytical derivatives of the objective
+  //                           function
+  // ERROR if(con_der_mode>=2) (2=2^1 = 1st derivative) this function does not
+  //                           support analytical derivatives of the constraint
+  //                           function
+
+  //printf("maxConDerMode=%d con_der_mode=%d maxObjDerMode=%d obj_der_mode=%d\n",
+  //maxConDerMode,con_der_mode,maxObjDerMode,obj_der_mode);
+
+  //might want to replace this with a thrown exception
+  assert((maxObjDerMode<=1)&&(maxConDerMode<=1)&&
+	 (0<=obj_der_mode)&&(obj_der_mode<=maxObjDerMode)&&
+	 (0<=con_der_mode)&&(con_der_mode<=maxConDerMode)&&
+	 ((1<=obj_der_mode)||(1<=con_der_mode)));
+
+  //if theta was the same as the last time we called this function than we can reuse some of the things we calculated last time
+
+  if(prevTheta.getNElems()!=numTheta) {
+    //different number of elements means we can't reuse
+    prevTheta.newSize(numTheta,1);
+    prevObjDerMode=prevConDerMode=0;
+  }
+  else
+    for(int k=0; k<numTheta; ++k)
+      if(prevTheta(k,0)!=theta(k,0)) {
+	//some parameter changed so we can't reuse
+	prevObjDerMode=prevConDerMode=0;
+	break;
+      }
+
+  if((obj_der_mode<=prevObjDerMode)&&
+     (con_der_mode<=prevConDerMode)) {
+    //we've already calculated everything you just asked for so reuse it
+    return;
+  }
+
+  //record the current theta as the previous theta so next time we can tell
+  //if we should reuse the stuff we calculate this time
+  if((prevObjDerMode==0)&&(prevConDerMode==0))
+    for(int k=0; k<numTheta; ++k)
+      prevTheta(k,0)=theta(k,0);
+
+  if(prevObjDerMode==0) {
+    //fill R with the build data "correlation matrix" (R is a member variable)
+    //for Kriging R is actually a correlation matrix (it is real, symmetric,
+    //positive definite and has all ones on the diagonal) for GEK it is
+    //real symmetric, and positive definite but does not have all ones on the
+    //diagonal, but the GEK R can be equilibrated/scaled to an honest to
+    //goodness correlation matrix.
+    correlation_matrix(theta);
+
+    //we need to perform a LU decomposition of R and calculate the
+    //determinant of R, I have replaced LU with Cholesky because it's
+    //better/faster, see
+    //http://en.wikipedia.org/wiki/Determinant#Determinant_from_LU_decomposition
+    //for how to efficiently compute the determinant from an LU factorization
+
+    int chol_info=0;
+    if(ifPrescribedNug==true) {
+      //the user prescribed a nugget for us to use, e.g. for when there is
+      //measurement error of known magnitude
+      apply_nugget_build(); //modify R by a nugget in place
+      reorderCopyRtoRChol();
+
+      Chol_fact_workspace(RChol,scaleRChol,rcondDblWork,rcondIntWork,
+			  chol_info,rcondR);
+      //Pivoted Cholesky o G*R^-1*G^T does not require pivoted Cholesky of R
+      //so the size of Gtran could have changed
+      nTrend=numTrend(polyOrderRequested,0);
+      if(Gtran.getNCols() < nTrend) {
+	Gtran.newSize(numEqnAvail,nTrend);
+	for(int itrend=0; itrend<nTrend; ++itrend)
+	  for(int i=0; i<numEqnAvail; ++i)
+	    Gtran(i,itrend)=Gall(itrend,i);
+      }
+
+    } else if(ifChooseNug==true) {
+      //the user wants us to select a small nugget to fix ill-conditioning of R
+      nuggetSelectingCholR();
+      //Pivoted Cholesky o G*R^-1*G^T does not require pivoted Cholesky of R
+      //so the size of Gtran could have changed
+      nTrend=numTrend(polyOrderRequested,0);
+      if(Gtran.getNCols() < nTrend) {
+	Gtran.newSize(numEqnAvail,nTrend);
+	for(int itrend=0; itrend<nTrend; ++itrend)
+	  for(int i=0; i<numEqnAvail; ++i)
+	    Gtran(i,itrend)=Gall(itrend,i);
+      }
+    }else {
+      //the user wants us to fix ill-conditioning of R by using Pivoted Cholesky
+      //to select an optimal subset of points from which to build the Kriging
+      //(or Gradient Enhanced Kriging) model
+      equationSelectingCholR();
+    }
+    double min_allowed_rcond=1.0/maxCondNum;
+    //nTrend=numTrend(polyOrder,0);
+    nTrend=numTrend(polyOrderRequested,0);
+
+    if((rcondR<=min_allowed_rcond)) { //||(numRowsR<=nTrend)) {
+      printf("singular correlation matrix rcondR=%g numRowsR=%d numTrend=%d numEqnAvail=%d\n",
+	     rcondR,numRowsR,nTrend,numEqnAvail);
+      MtxDbl corr_len_temp(numVarsr,1);
+      get_corr_len_from_theta(corr_len_temp, theta);
+      printf("corr_len=[%g",corr_len_temp(0,0));
+      for(int kk=1; kk<numVarsr; ++kk)
+	printf(",%g",corr_len_temp(kk,0));
+      printf("]^T\n");
+
+      obj=HUGE_VAL; //the objective would actually be infinite, but it might
+      //say nan if we let it continue and we don't want to trust the optimizer
+      //to handle nan's correctly
+
+      con.newSize(numConFunc,1);
+      con(0,0)=1.0-rcondR*maxCondNum;
+      //there should only be 1 constraint but just in case we'll fill the rest
+      //as being violated
+      for(int i=1; i<numConFunc; ++i)
+	con(i,0)=1.0; //say the constraints are violated,
+
+      //no point in wasting computation on something useless by continuing so
+      //return early
+      return;
+    }
+
+    double log_determinant_R = 0.0; //need to do this to avoid underflow error for large numbers of points, log(0)=-inf
+    for (int i = 0; i < numRowsR; ++i)
+      log_determinant_R += std::log(RChol(i,i));
+    log_determinant_R *= 2.0; //only multiply by 2 for Cholesky factorization
+    //of R because det(L)=det(U) and det(R)=det(L)*det(U)=det(L)^2
+    //so log(det(R))=2*log(det(L))
+
+    //if a future developer wants to switch back from cholesky to LU (and I
+    //strongly recommend against that) you'll need to do a
+    //determinant_R=std::fabs(determinant_R); //for LU factorization
+    //because "The determinant of a positive definite matrix is always
+    //positive" http://mathworld.wolfram.com/PositiveDefiniteMatrix.html and
+    //det(R)=det(pivot Mtx)*det(L)*det(U); det(L)=1, det(U) is what we'd
+    //calculated above for LU and det(pivot Mtx)= +/- 1, which is why you'd
+    //need to do the fabs(det(U)) if you used LU decomp instead of Cholesky
+
+    //Do the generalized (by R^-1) least squares using min # of ops
+    //printf("numPoints=%d numPointsKeep=%d numRowsR=%d nTrend=%d\n",
+    //   numPoints,numPointsKeep,numRowsR,nTrend);
+
+
+    Rinv_Gtran.newSize(numRowsR,nTrend); //precompute and store
+    solve_after_Chol_fact(Rinv_Gtran,RChol,Gtran);
+
+    G_Rinv_Gtran.newSize(nTrend,nTrend);
+    matrix_mult(G_Rinv_Gtran,Gtran,Rinv_Gtran,0.0,1.0,'T','N');
+
+    trendSelectingPivotedCholesky();
+    //Chol_fact_workspace(G_Rinv_Gtran_Chol,G_Rinv_Gtran_Chol_Scale,G_Rinv_Gtran_Chol_DblWork,G_Rinv_Gtran_Chol_IntWork,chol_info,rcond_G_Rinv_Gtran);
+    if((rcond_G_Rinv_Gtran<min_allowed_rcond)||(numRowsR<=nTrend)) {
+      //we could instead use pivoted cholesky to adaptively selected an optimal
+      //subset of trend basis functions (i.e. it could be lower in some
+      //dimensions than in others or have quadratic but not linear in certain
+      //dimensions etc) then we wouldn't have to worry about this
+
+      std::cerr << "R is not singular but G*R^-1*G^T is numerically "
+		<< "singular.  This is probably\ndue to you not having "
+		<< "enough UNIQUE values in one of your input dimensions\n"
+		<< "to support the utilized trend function even though "
+		<< "the total number of\npoints would normally be "
+		<< "sufficient for the selected trend." << std::endl;
+      obj=HUGE_VAL; //the objective would actually be infinite, but it might
+      //say nan if we let it continue and we don't want to trust the optimizer
+      //to handle nan's correctly
+
+      con.newSize(numConFunc,1);
+
+      //there should only be 1 constraint but just in case we'll fill them all
+      //as being violated
+      for(int i=0; i<numConFunc; ++i)
+	con(i,0)=1.0; //say the constraints are violated,
+
+      //no point in wasting computation on something useless by continuing so
+      //return early
+      return;
+    }
+
+#ifdef __KRIG_ERR_CHECK__
+    assert(chol_info==0);  //for debug, do something else for production
+#endif
+
+    double log_determinant_G_Rinv_Gtran=0.0;
+    for (int itrend = 0; itrend < nTrend; ++itrend)
+      log_determinant_G_Rinv_Gtran +=
+	std::log(G_Rinv_Gtran_Chol(itrend,itrend));
+    log_determinant_G_Rinv_Gtran *= 2.0; //only for Cholesky factorization
+
+    G_Rinv_Y.newSize(nTrend,1);
+    matrix_mult(G_Rinv_Y, Rinv_Gtran, Y, 0.0, 1.0, 'T', 'N');
+    betaHat.newSize(nTrend,1);
+
+    solve_after_Chol_fact(betaHat,G_Rinv_Gtran_Chol,G_Rinv_Y); //O(nTrend^2) ops
+    eps.copy(Y); //this will be eps=epsilon=Y-G(XR)^T*betaHat
+    matrix_mult(eps, Gtran, betaHat, 1.0, -1.0, 'N', 'N'); //eps=Y-G(XR)^T*betaHat
+    rhs.newSize(numRowsR,1);
+    solve_after_Chol_fact(rhs,RChol,eps);
+
+
+    //it's actually the log likelihood, which we want to maximize
+    //likelihood = -0.5*(numPoints*(std::log(4.0*std::acos(0.0))+std::log(estVarianceMLE)+1)
+    //		       +std::log(determinant_R)); //from Koehler and Owen
+
+#ifdef __NKM_UNBIASED_LIKE__
+    //derived following: C. E. Rasmussen & C. K. I. Williams, Gaussian Processes for Machine Learning, the MIT Press, 2006, ISBN 026218253X. c 2006 Massachusetts Institute of Technology. www.GaussianProcess.org/gpml...  we assume a "vague prior" (i.e. that we don't know anything) for betaHat, then like "Koehler and Owen" we replace the covariance matrix K with (unadjusted variance)*R (where R is the correlation matrix) and find unadjusted variance and betaHat through maximum likelihood.
+
+    //the unbiased estimate of unadjusted variance
+    estVarianceMLE = dot_product(eps,rhs)/(numRowsR-nTrend);
+
+    //the "per equationt" unbiased log(likelihood)
+    likelihood = -0.5*(std::log(estVarianceMLE)+(log_determinant_R+log_determinant_G_Rinv_Gtran)/(numRowsR-nTrend));
+#else
+    //derived the "Koehler and Owen" way (assumes we know the trend function, and is therefore biased
+
+    //the estimate of unadjusted variance
+    estVarianceMLE = dot_product(eps,rhs)/numRowsR; //the "Koehler and Owen" way
+
+    //the "per equation" log(likelihood)
+    likelihood = -0.5*(std::log(estVarianceMLE)+log_determinant_R/numRowsR);
+#endif
+
+    //if(likelihood>=DBL_MAX)
+    //printf("[estVarianceMLE=%g determinant_R=%g]",estVarianceMLE,determinant_R);
+
+    //the objective function being MINIMIZED is the negative of the log
+    //likelihood (on a per equation basis so numbers will be comparable
+    //regardless of how many equations there are)
+    obj=-likelihood;
+    //printf("[obj=%g]",obj);
+
+    prevObjDerMode=1; //increase prevObjDerMode to the current value
+    if((obj_der_mode==1)&&(con_der_mode<=prevConDerMode)) {
+      //we have everything we need so exit early
+      return;
+    }
+  }
+
+  if((prevConDerMode==0)&&(1<=con_der_mode)) {
+    //calculate the constraint on reciprocal condition number that ensures
+    //that the correlation matrix is well conditioned.
+    con.newSize(numConFunc,1);
+
+    if(!(1<=prevObjDerMode))
+      std::cerr << "We need to have already calculated rcondR (during the "
+		<< "calculation of the\nobjective function) in order to "
+		<< "calculate the constraint (on rcondR)\nfunction (where "
+		<< "rcondR is the reciprocal of the condition number of R,\n"
+		<< "and R is the ''correlation matrix'')." << std::endl;
+    else if(!(numConFunc==1))
+      std::cerr << "The calling function is asking us for more than one "
+		<< "constraint function\nbut we only have one constraint "
+		<< "function; only rcondR (the reciprocal of\nthe "
+		<< "condition number of the ''correlation matrix'', R) is "
+		<< "constrained." << std::endl;
+    assert((1<=prevObjDerMode)&&(numConFunc==1));
+
+    //the matrix is considered "ill-conditioned" if the following constraint
+    //equation is greater than zero
+    con(0,0)=1.0-rcondR*maxCondNum;
+
+    prevConDerMode=1; //increase prevConDerMode to current value
+    if((con_der_mode==1)&&(obj_der_mode<=prevObjDerMode)) {
+      //we have everything we need so exit early
+      return;
+    }
+  }
+
+  return;
+}
+
+
+void KrigingModel::getRandGuess(MtxDbl& guess) const
+{
+  int mymod = 1048576; //2^20 instead of 10^6 to be kind to the computer
+  guess.newSize(numVarsr,1);
+  for(int k=0; k<numVarsr; k++) {
+    guess(k,0) = (std::rand() % mymod)*(maxNatLogCorrLen-minNatLogCorrLen)/mymod+
+      minNatLogCorrLen; //this returns a random nat_log_corr_len which is the space we need to search in
+  }
+  return;
+}
+
+// BMA TODO: These need to be moved to optimizer and then any defauls
+// overridden here
+
+void KrigingModel::set_conmin_parameters(OptimizationProblem& opt) const
+{
+  //set conmin specific parameters for this problem
+  if((maxObjDerMode==1)&&(maxConDerMode==1)) {
+    //use numerical  gradients of objective and constraints
+    opt.conminData.nfdg = 0;
+  } else {
+    std::cerr << "This Kriging/Gradient-Enhanced-Kriging model does not "
+	      << "support analytical\nderivatives of the objective "
+	      << "(negative per equation log likelihood) or\nconstraint "
+	      << "(reciprocal condition number) functions." << std::endl;
+    assert(false);
+  }
+
+  opt.conminData.iprint = 0; //ammount of to screen output from Conmin
+  opt.conminData.itmax  = maxTrials; //maximum # of Conmin iterations
+  opt.conminData.fdch   = 1.0e-2; //Relative finite difference step size.
+  opt.conminData.fdchm  = 1.0e-2; //Absolute finite difference step size.
+  opt.conminData.ct     = -0.1; // Constraint thickness parameter, The absolute value of CT decreases in magnitude during optimization.
+  opt.conminData.ctmin  = 0.004; //Minimum absolute value of CT used during optimization.
+  opt.conminData.ctl    = -0.01; //Constraint thickness parameter for linear and side constraints.
+  opt.conminData.ctlmin = 0.001; //Minimum value of CTL used during optimization.
+  opt.conminData.delfun = 0.001; //Relative convergence criterion threshold, Threshold for the minimum relative change in the objective function
+  opt.conminData.dabfun = 0.001; //Absolute convergence criterion threshold. Threshold for the minimum relative change in the objective function
+  opt.conminData.nside  = 1; //side constraints parameter
+  opt.conminData.itrm   = 3; //diminishing return criterion iteration number
+  opt.conminData.icndir = numTheta+1; //conjugate direction restart parameter
+}
+
+void KrigingModel::set_direct_parameters(OptimizationProblem& opt) const
+{
+  opt.directData.minBoxSize = -1.0;
+  opt.directData.volBoxSize = -1.0;
+  //opt.directData.minBoxSize = 1.0e-15;
+  //opt.directData.volBoxSize = 1.0e-15;
+  //opt.directData.minBoxSize = 1.0e-3;
+  //opt.directData.volBoxSize = 1.0e-5;
+  opt.directData.solutionTarget = -DBL_MAX;
+  opt.directData.convergenceTol = 1.0e-4;
+  opt.directData.maxFunctionEvals = maxTrials;
+  opt.directData.maxIterations = 1000;
+  opt.directData.verboseOutput = false;
+  opt.directData.constraintsPresent = true;
+}
+
+} // end namespace nkm
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/DakotaInterface.cpp
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/DakotaInterface.cpp	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/DakotaInterface.cpp	(revision 24593)
@@ -0,0 +1,1358 @@
+/*  _______________________________________________________________________
+
+    DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
+    Copyright 2014 Sandia Corporation.
+    This software is distributed under the GNU Lesser General Public License.
+    For more information, see the README file in the top Dakota directory.
+    _______________________________________________________________________ */
+
+//- Class:        Interface
+//- Description:  Class implementation for abstract interface base class
+//- Owner:        Michael Eldred
+
+#include "DakotaInterface.hpp"
+#include "ProblemDescDB.hpp"
+#include "DakotaVariables.hpp"
+
+#include "SysCallApplicInterface.hpp"
+
+#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H)
+#include "ForkApplicInterface.hpp"
+#elif defined(_WIN32) // or _MSC_VER (native MSVS compilers)
+#include "SpawnApplicInterface.hpp"
+#endif // HAVE_SYS_WAIT_H, HAVE_UNISTD_H
+
+// Direct interfaces
+#ifdef DAKOTA_GRID
+#include "GridApplicInterface.hpp"
+#endif // DAKOTA_GRID
+#ifdef DAKOTA_MATLAB
+#include "MatlabInterface.hpp"
+#endif // DAKOTA_MATLAB
+#ifdef DAKOTA_PYTHON
+#include "PythonInterface.hpp"
+#endif // DAKOTA_PYTHON
+#ifdef DAKOTA_SCILAB
+#include "ScilabInterface.hpp"
+#endif // DAKOTA_SCILAB
+#include "TestDriverInterface.hpp"
+
+#include "ApproximationInterface.hpp"
+
+#ifdef HAVE_AMPL
+#undef NO // avoid name collision from UTILIB
+#include "ampl/asl.h"
+#endif // HAVE_AMPL
+
+//#define DEBUG
+//#define REFCOUNT_DEBUG
+
+namespace Dakota {
+
+
+/** This constructor is the one which must build the base class data for all
+    inherited interfaces.  get_interface() instantiates a derived class letter
+    and the derived constructor selects this base class constructor in its
+    initialization list (to avoid the recursion of the base class constructor
+    calling get_interface() again).  Since this is the letter and the letter
+    IS the representation, interfaceRep is set to NULL (an uninitialized
+    pointer causes problems in ~Interface). */
+Interface::Interface(BaseConstructor, const ProblemDescDB& problem_db):
+  interfaceType(problem_db.get_ushort("interface.type")),
+  interfaceId(problem_db.get_string("interface.id")), algebraicMappings(false),
+  coreMappings(true), outputLevel(problem_db.get_short("method.output")),
+  currEvalId(0), fineGrainEvalCounters(outputLevel > NORMAL_OUTPUT),
+  evalIdCntr(0), newEvalIdCntr(0), evalIdRefPt(0), newEvalIdRefPt(0),
+  multiProcEvalFlag(false), ieDedMasterFlag(false),
+  // See base constructor in DakotaIterator.cpp for full discussion of output
+  // verbosity.  Interfaces support the full granularity in verbosity.
+  appendIfaceId(true), interfaceRep(NULL), referenceCount(1), asl(NULL)
+{
+#ifdef DEBUG
+  outputLevel = DEBUG_OUTPUT;
+#endif // DEBUG
+
+  // Process the algebraic_mappings file (an AMPL .nl file) to get the number
+  // of variables/responses (currently, the tags are converted to index arrays
+  // at evaluation time, using the passed vars and response).
+  // TO DO: parallel bcast of data or very proc reads file?
+  const String& ampl_file_name
+    = problem_db.get_string("interface.algebraic_mappings");
+  if (!ampl_file_name.empty()) {
+#ifdef HAVE_AMPL
+    algebraicMappings = true;
+    bool hess_flag
+      = (problem_db.get_string("responses.hessian_type") == "analytic");
+    asl = (hess_flag) ? ASL_alloc(ASL_read_pfgh) : ASL_alloc(ASL_read_fg);
+    // allow user input of either stub or stub.nl
+    String stub = (strends(ampl_file_name, ".nl")) ?
+      String(ampl_file_name, 0, ampl_file_name.size() - 3) : ampl_file_name;
+    //std::ifstream ampl_nl(ampl_file_name);
+    fint stub_str_len = stub.size();
+    // BMA NOTE: casting away the constness as done historically in DakotaString
+    char* nonconst_stub = (char*) stub.c_str();
+    FILE* ampl_nl = jac0dim(nonconst_stub, stub_str_len);
+    if (!ampl_nl) {
+      Cerr << "\nError: failure opening " << ampl_file_name << std::endl;
+      abort_handler(IO_ERROR);
+    }
+    int rtn = (hess_flag) ? pfgh_read(ampl_nl, ASL_return_read_err)
+                          :   fg_read(ampl_nl, ASL_return_read_err);
+    if (rtn) {
+      Cerr << "\nError: AMPL processing problem with " << ampl_file_name
+	   << std::endl;
+      abort_handler(IO_ERROR);
+    }
+
+    // extract input/output tag lists
+    String row = stub + ".row", col = stub + ".col", ampl_tag;
+
+    std::ifstream ampl_col(col.c_str());
+    if (!ampl_col) {
+      Cerr << "\nError: failure opening " << col.c_str() << std::endl;
+      abort_handler(IO_ERROR);
+    }
+    algebraicVarTags.resize(n_var);
+    for (size_t i=0; i<n_var; i++) {
+      std::getline(ampl_col, ampl_tag);
+      if (ampl_col.good())
+	algebraicVarTags[i] = ampl_tag;
+      else {
+	Cerr << "\nError: failure reading AMPL col file " << col.c_str()
+	     << std::endl;
+	abort_handler(IO_ERROR);
+      }
+    }
+
+    std::ifstream ampl_row(row.c_str());
+    if (!ampl_row) {
+      Cerr << "\nError: failure opening " << row.c_str() << std::endl;
+      abort_handler(IO_ERROR);
+    }
+    algebraicFnTags.resize(n_obj+n_con);
+    algebraicFnTypes.resize(n_obj+n_con);
+    algebraicConstraintWeights.resize(n_con);
+    for (size_t i=0; i<n_obj+n_con; i++) {
+      getline(ampl_row, ampl_tag);
+      if (ampl_row.good()) {
+	algebraicFnTags[i] = ampl_tag;
+	algebraicFnTypes[i] = algebraic_function_type(ampl_tag);
+      }
+      else {
+	Cerr << "\nError: failure reading AMPL row file " << row.c_str()
+	     << std::endl;
+	abort_handler(IO_ERROR);
+      }
+    }
+
+#ifdef DEBUG
+    Cout << ">>>>> algebraicVarTags =\n" << algebraicVarTags
+	 << "\n>>>>> algebraicFnTags =\n" << algebraicFnTags
+	 << "\n>>>>> algebraicFnTypes =\n" << algebraicFnTypes << std::endl;
+#endif
+
+#else
+    Cerr << "\nError: algebraic_mappings not supported without the AMPL solver "
+	 << "library provided with the Acro package." << std::endl;
+    abort_handler(-1);
+#endif // HAVE_AMPL
+  }
+
+#ifdef REFCOUNT_DEBUG
+  Cout << "Interface::Interface(BaseConstructor, ProblemDescDB&) called to "
+       << "build base class data for letter object." << std::endl;
+#endif
+}
+
+
+Interface::Interface(NoDBBaseConstructor, size_t num_fns, short output_level):
+  interfaceId("NO_SPECIFICATION"), algebraicMappings(false), coreMappings(true),
+  outputLevel(output_level), currEvalId(0),
+  fineGrainEvalCounters(outputLevel > NORMAL_OUTPUT), evalIdCntr(0),
+  newEvalIdCntr(0), evalIdRefPt(0), newEvalIdRefPt(0), multiProcEvalFlag(false),
+  ieDedMasterFlag(false), appendIfaceId(true), interfaceRep(NULL),
+  referenceCount(1)
+{
+#ifdef DEBUG
+  outputLevel = DEBUG_OUTPUT;
+#endif // DEBUG
+
+#ifdef REFCOUNT_DEBUG
+  Cout << "Interface::Interface(NoDBBaseConstructor) called to build base "
+       << "class data for letter object." << std::endl;
+#endif
+}
+
+
+/** used in Model envelope class instantiations */
+Interface::Interface(): interfaceRep(NULL), referenceCount(1)
+{ }
+
+
+/** Used in Model instantiation to build the envelope.  This constructor
+    only needs to extract enough data to properly execute get_interface, since
+    Interface::Interface(BaseConstructor, problem_db) builds the
+    actual base class data inherited by the derived interfaces. */
+Interface::Interface(ProblemDescDB& problem_db): referenceCount(1)
+{
+#ifdef REFCOUNT_DEBUG
+  Cout << "Interface::Interface(ProblemDescDB&) called to instantiate envelope."
+       << std::endl;
+#endif
+
+  // Set the rep pointer to the appropriate interface type
+  interfaceRep = get_interface(problem_db);
+  if (!interfaceRep) // bad type or insufficient memory
+    abort_handler(-1);
+}
+
+
+/** used only by the envelope constructor to initialize interfaceRep
+    to the appropriate derived type. */
+Interface* Interface::get_interface(ProblemDescDB& problem_db)
+{
+  const unsigned short interface_type = problem_db.get_ushort("interface.type");
+#ifdef REFCOUNT_DEBUG
+  Cout << "Envelope instantiating letter: Getting interface "
+       << interface_enum_to_string(interface_type) << std::endl;
+#endif
+
+  // In the case where a derived interface type has been selected for managing
+  // analysis_drivers, then this determines the letter instantiation and any
+  // algebraic mappings are overlayed by ApplicationInterface.
+  const String& algebraic_map_file
+    = problem_db.get_string("interface.algebraic_mappings");
+  if (interface_type == SYSTEM_INTERFACE)
+    return new SysCallApplicInterface(problem_db);
+
+  else if (interface_type == FORK_INTERFACE) {
+#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) // includes CYGWIN/MINGW
+    return new ForkApplicInterface(problem_db);
+#elif defined(_WIN32) // or _MSC_VER (native MSVS compilers)
+    return new SpawnApplicInterface(problem_db);
+#else
+    Cerr << "Fork interface requested, but not enabled in this DAKOTA "
+	 << "executable." << std::endl;
+    return NULL;
+#endif
+  }
+
+  else if (interface_type == TEST_INTERFACE)
+    return new TestDriverInterface(problem_db);
+  // Note: in the case of a plug-in direct interface, this object gets replaced
+  // using Interface::assign_rep().  Error checking in DirectApplicInterface::
+  // derived_map_ac() should catch if this replacement fails to occur properly.
+
+#ifdef DAKOTA_GRID
+  else if (interface_type == GRID_INTERFACE)
+    return new GridApplicInterface(problem_db);
+#endif
+
+  else if (interface_type == MATLAB_INTERFACE) {
+#ifdef DAKOTA_MATLAB
+    return new MatlabInterface(problem_db);
+#else
+    Cerr << "Direct Matlab interface requested, but not enabled in this "
+	 << "DAKOTA executable." << std::endl;
+      return NULL;
+#endif
+  }
+
+  else if (interface_type == PYTHON_INTERFACE) {
+#ifdef DAKOTA_PYTHON
+    return new PythonInterface(problem_db);
+#else
+    Cerr << "Direct Python interface requested, but not enabled in this "
+	 << "DAKOTA executable." << std::endl;
+    return NULL;
+#endif
+  }
+
+  else if (interface_type == SCILAB_INTERFACE) {
+#ifdef DAKOTA_SCILAB
+    return new ScilabInterface(problem_db);
+#else
+    Cerr << "Direct Scilab interface requested, but not enabled in this "
+	 << "DAKOTA executable." << std::endl;
+    return NULL;
+#endif
+  }
+
+  // Should not be needed since ApproximationInterface is plugged-in from
+  // DataFitSurrModel using Interface::assign_rep().
+  //else if (interface_type == APPROX_INTERFACE)
+  //  return new ApproximationInterface(problem_db, num_acv, num_fns);
+
+  // In the case where only algebraic mappings are used, then no derived map
+  // functionality is needed and ApplicationInterface is used for the letter.
+  else if (!algebraic_map_file.empty()) {
+#ifdef DEBUG
+    Cout << ">>>>> new ApplicationInterface: " << algebraic_map_file
+	 << std::endl;
+#endif // DEBUG
+    return new ApplicationInterface(problem_db);
+  }
+
+  // If the interface type is empty (e.g., from default DataInterface creation
+  // in ProblemDescDB::check_input()), then ApplicationInterface is the letter.
+  else if (interface_type == DEFAULT_INTERFACE) {
+    Cerr << "Warning: empty interface type in Interface::get_interface()."
+	 << std::endl;
+    return new ApplicationInterface(problem_db);
+  }
+
+  else {
+    Cerr << "Invalid interface: " << interface_enum_to_string(interface_type)
+	 << std::endl;
+    return NULL;
+  }
+}
+
+
+/** Copy constructor manages sharing of interfaceRep and incrementing
+    of referenceCount. */
+Interface::Interface(const Interface& interface_in)
+{
+  // Increment new (no old to decrement)
+  interfaceRep = interface_in.interfaceRep;
+  if (interfaceRep) // Check for an assignment of NULL
+    ++interfaceRep->referenceCount;
+
+#ifdef REFCOUNT_DEBUG
+  Cout << "Interface::Interface(Interface&)" << std::endl;
+  if (interfaceRep)
+    Cout << "interfaceRep referenceCount = " << interfaceRep->referenceCount
+	 << std::endl;
+#endif
+}
+
+
+/** Assignment operator decrements referenceCount for old interfaceRep, assigns
+    new interfaceRep, and increments referenceCount for new interfaceRep. */
+Interface Interface::operator=(const Interface& interface_in)
+{
+  if (interfaceRep != interface_in.interfaceRep) { // normal case: old != new
+    // Decrement old
+    if (interfaceRep) // Check for NULL
+      if ( --interfaceRep->referenceCount == 0 )
+	delete interfaceRep;
+    // Assign and increment new
+    interfaceRep = interface_in.interfaceRep;
+    if (interfaceRep) // Check for NULL
+      ++interfaceRep->referenceCount;
+  }
+  // else if assigning same rep, then do nothing since referenceCount
+  // should already be correct
+
+#ifdef REFCOUNT_DEBUG
+  Cout << "Interface::operator=(Interface&)" << std::endl;
+  if (interfaceRep)
+    Cout << "interfaceRep referenceCount = " << interfaceRep->referenceCount
+	 << std::endl;
+#endif
+
+  return *this; // calls copy constructor since returned by value
+}
+
+
+/** Destructor decrements referenceCount and only deletes interfaceRep
+    if referenceCount is zero. */
+Interface::~Interface()
+{
+  // Check for NULL pointer
+  if (interfaceRep) {
+    --interfaceRep->referenceCount;
+#ifdef REFCOUNT_DEBUG
+    Cout << "interfaceRep referenceCount decremented to "
+         << interfaceRep->referenceCount << std::endl;
+#endif
+    if (interfaceRep->referenceCount == 0) {
+#ifdef REFCOUNT_DEBUG
+      Cout << "deleting interfaceRep" << std::endl;
+#endif
+      delete interfaceRep;
+    }
+  }
+}
+
+
+/** Similar to the assignment operator, the assign_rep() function
+    decrements referenceCount for the old interfaceRep and assigns the
+    new interfaceRep.  It is different in that it is used for
+    publishing derived class letters to existing envelopes, as opposed
+    to sharing representations among multiple envelopes (in particular,
+    assign_rep is passed a letter object and operator= is passed an
+    envelope object).  Letter assignment supports two models as
+    governed by ref_count_incr:
+
+    \li ref_count_incr = true (default): the incoming letter belongs to
+    another envelope.  In this case, increment the reference count in the
+    normal manner so that deallocation of the letter is handled properly.
+
+    \li ref_count_incr = false: the incoming letter is instantiated on the
+    fly and has no envelope.  This case is modeled after get_interface():
+    a letter is dynamically allocated using new and passed into assign_rep,
+    the letter's reference count is not incremented, and the letter is not
+    remotely deleted (its memory management is passed over to the envelope). */
+void Interface::assign_rep(Interface* interface_rep, bool ref_count_incr)
+{
+  if (interfaceRep == interface_rep) {
+    // if ref_count_incr = true (rep from another envelope), do nothing as
+    // referenceCount should already be correct (see also operator= logic).
+    // if ref_count_incr = false (rep from on the fly), then this is an error.
+    if (!ref_count_incr) {
+      Cerr << "Error: duplicated interface_rep pointer assignment without "
+	   << "reference count increment in Interface::assign_rep()."
+	   << std::endl;
+      abort_handler(-1);
+    }
+  }
+  else { // normal case: old != new
+    // Decrement old
+    if (interfaceRep) // Check for NULL
+      if ( --interfaceRep->referenceCount == 0 )
+	delete interfaceRep;
+    // Assign new
+    interfaceRep = interface_rep;
+    // Increment new
+    if (interfaceRep && ref_count_incr) // Check for NULL & honor ref_count_incr
+      interfaceRep->referenceCount++;
+  }
+
+#ifdef REFCOUNT_DEBUG
+  Cout << "Interface::assign_rep(Interface*)" << std::endl;
+  if (interfaceRep)
+    Cout << "interfaceRep referenceCount = " << interfaceRep->referenceCount
+	 << std::endl;
+#endif
+}
+
+
+void Interface::fine_grained_evaluation_counters(size_t num_fns)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->fine_grained_evaluation_counters(num_fns);
+  else if (!fineGrainEvalCounters) { // letter (not virtual)
+    init_evaluation_counters(num_fns);
+    fineGrainEvalCounters = true;
+  }
+}
+
+
+void Interface::init_evaluation_counters(size_t num_fns)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->init_evaluation_counters(num_fns);
+  else { // letter (not virtual)
+    //if (fnLabels.empty()) {
+    //  fnLabels.resize(num_fns);
+    //  build_labels(fnLabels, "response_fn_"); // generic resp fn labels
+    //}
+    if (fnValCounter.size() != num_fns) {
+      fnValCounter.assign(num_fns, 0);     fnGradCounter.assign(num_fns, 0);
+      fnHessCounter.assign(num_fns, 0);    newFnValCounter.assign(num_fns, 0);
+      newFnGradCounter.assign(num_fns, 0); newFnHessCounter.assign(num_fns, 0);
+      fnValRefPt.assign(num_fns, 0);       fnGradRefPt.assign(num_fns, 0);
+      fnHessRefPt.assign(num_fns, 0);      newFnValRefPt.assign(num_fns, 0);
+      newFnGradRefPt.assign(num_fns, 0);   newFnHessRefPt.assign(num_fns, 0);
+    }
+  }
+}
+
+
+void Interface::set_evaluation_reference()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->set_evaluation_reference();
+  else { // letter (not virtual)
+
+    evalIdRefPt    = evalIdCntr;
+    newEvalIdRefPt = newEvalIdCntr;
+
+    if (fineGrainEvalCounters) {
+      size_t i, num_fns = fnValCounter.size();
+      for (i=0; i<num_fns; i++) {
+	fnValRefPt[i]     =     fnValCounter[i];
+	newFnValRefPt[i]  =  newFnValCounter[i];
+	fnGradRefPt[i]    =    fnGradCounter[i];
+	newFnGradRefPt[i] = newFnGradCounter[i];
+	fnHessRefPt[i]    =    fnHessCounter[i];
+	newFnHessRefPt[i] = newFnHessCounter[i];
+      }
+    }
+  }
+}
+
+
+void Interface::
+print_evaluation_summary(std::ostream& s, bool minimal_header,
+			 bool relative_count) const
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->print_evaluation_summary(s, minimal_header, relative_count);
+  else { // letter (not virtual)
+
+    // standard evaluation summary
+    if (minimal_header) {
+      if (interfaceId.empty())
+	s << "  Interface evaluations";
+      else
+	s << "  " << interfaceId << " evaluations";
+    }
+    else {
+      s << "<<<<< Function evaluation summary";
+      if (!interfaceId.empty())
+	s << " (" << interfaceId << ')';
+    }
+    int     fn_evals = (relative_count) ? evalIdCntr - evalIdRefPt
+                                        : evalIdCntr;
+    int new_fn_evals = (relative_count) ? newEvalIdCntr - newEvalIdRefPt
+                                        : newEvalIdCntr;
+    s << ": " << fn_evals << " total (" << new_fn_evals << " new, "
+      << fn_evals - new_fn_evals << " duplicate)\n";
+
+    // detailed evaluation summary
+    if (fineGrainEvalCounters) {
+      size_t i, num_fns = std::min(fnValCounter.size(), fnLabels.size());
+      for (i=0; i<num_fns; i++) {
+	int t_v = (relative_count) ?     fnValCounter[i] -     fnValRefPt[i]
+	                           :     fnValCounter[i];
+	int n_v = (relative_count) ?  newFnValCounter[i] -  newFnValRefPt[i]
+	                           :  newFnValCounter[i];
+	int t_g = (relative_count) ?    fnGradCounter[i] -    fnGradRefPt[i]
+	                           :    fnGradCounter[i];
+	int n_g = (relative_count) ? newFnGradCounter[i] - newFnGradRefPt[i]
+	                           : newFnGradCounter[i];
+	int t_h = (relative_count) ?    fnHessCounter[i] -    fnHessRefPt[i]
+	                           :    fnHessCounter[i];
+	int n_h = (relative_count) ? newFnHessCounter[i] - newFnHessRefPt[i]
+	                           : newFnHessCounter[i];
+	s << std::setw(15) << fnLabels[i] << ": "
+	  << t_v << " val ("  << n_v << " n, " << t_v - n_v << " d), "
+	  << t_g << " grad (" << n_g << " n, " << t_g - n_g << " d), "
+	  << t_h << " Hess (" << n_h << " n, " << t_h - n_h << " d)\n";
+      }
+    }
+  }
+}
+
+
+/// default implementation just sets the list of eval ID tags;
+/// derived classes containing additional models or interfaces should
+/// override (currently no use cases)
+void Interface::
+eval_tag_prefix(const String& eval_id_str, bool append_iface_id)
+{
+  if (interfaceRep)
+    interfaceRep->eval_tag_prefix(eval_id_str, append_iface_id);
+  else {
+    evalTagPrefix = eval_id_str;
+    appendIfaceId = append_iface_id;
+  }
+}
+
+
+void Interface::map(const Variables& vars, const ActiveSet& set,
+		    Response& response, bool asynch_flag)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->map(vars, set, response, asynch_flag);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual map function.\n"
+         << "No default map defined at Interface base class." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+init_algebraic_mappings(const Variables& vars, const Response& response)
+{
+  size_t i, num_alg_vars = algebraicVarTags.size(),
+    num_alg_fns = algebraicFnTags.size();
+
+  algebraicACVIndices.resize(num_alg_vars);
+  algebraicACVIds.resize(num_alg_vars);
+  StringMultiArrayConstView acv_labels = vars.all_continuous_variable_labels();
+  SizetMultiArrayConstView  acv_ids    = vars.all_continuous_variable_ids();
+  for (i=0; i<num_alg_vars; ++i) {
+    // Note: variable mappings only support continuous variables.
+    //       discrete variables are not directly supported by ASL interface.
+    size_t acv_index = find_index(acv_labels, algebraicVarTags[i]);
+    //size_t adv_index = find_index(adv_labels, algebraicVarTags[i]);
+    if (acv_index == _NPOS) { // && adv_index == _NPOS) {
+      Cerr << "\nError: AMPL column label " << algebraicVarTags[i] << " does "
+	   <<"not exist in DAKOTA continuous variable descriptors.\n"
+	   << std::endl;
+      abort_handler(INTERFACE_ERROR);
+    }
+    else {
+      algebraicACVIndices[i] = acv_index;
+      //algebraicADVIndices[i] = adv_index;
+      algebraicACVIds[i] = acv_ids[acv_index];
+    }
+  }
+
+  algebraicFnIndices.resize(num_alg_fns);
+  const StringArray& fn_labels = response.function_labels();
+  for (size_t i=0; i<num_alg_fns; ++i) {
+    size_t fn_index = Pecos::find_index(fn_labels, algebraicFnTags[i]);
+    if (fn_index == _NPOS) {
+      Cerr << "\nError: AMPL row label " << algebraicFnTags[i] << " does not "
+	   <<"exist in DAKOTA response descriptors.\n" << std::endl;
+      abort_handler(INTERFACE_ERROR);
+    }
+    else
+      algebraicFnIndices[i] = fn_index;
+  }
+}
+
+
+void Interface::
+asv_mapping(const ActiveSet& total_set, ActiveSet& algebraic_set,
+	    ActiveSet& core_set)
+{
+  const ShortArray& total_asv = total_set.request_vector();
+  const SizetArray& total_dvv = total_set.derivative_vector();
+
+  // algebraic_asv/dvv:
+
+  // the algebraic active set is defined over reduced algebraic function
+  // and variable spaces, rather than the original spaces.  This simplifies
+  // algebraic_mappings() and allows direct copies of data from AMPL.
+  size_t i, num_alg_fns = algebraicFnTags.size(),
+    num_alg_vars = algebraicVarTags.size();
+  ShortArray algebraic_asv(num_alg_fns);
+  SizetArray algebraic_dvv(num_alg_vars);
+  for (i=0; i<num_alg_fns; i++) // map total_asv to algebraic_asv
+    algebraic_asv[i] = total_asv[algebraicFnIndices[i]];
+
+  algebraic_set.request_vector(algebraic_asv);
+  algebraic_set.derivative_vector(algebraic_dvv);
+  algebraic_set.derivative_start_value(1);
+
+  // core_asv/dvv:
+
+  // for now, core_asv is the same as total_asv, since there is no mechanism
+  // yet to determine if the algebraic_mapping portion is the complete
+  // definition (for which core_asv requests could be turned off).
+  core_set.request_vector(total_asv);
+  core_set.derivative_vector(total_dvv);
+}
+
+
+void Interface::
+asv_mapping(const ActiveSet& algebraic_set, ActiveSet& total_set)
+{
+  const ShortArray& algebraic_asv = algebraic_set.request_vector();
+  size_t i, num_alg_fns = algebraicFnTags.size();
+  for (i=0; i<num_alg_fns; i++) // map algebraic_asv to total_asv
+    total_set.request_value(algebraic_asv[i], algebraicFnIndices[i]);
+}
+
+
+void Interface::
+algebraic_mappings(const Variables& vars, const ActiveSet& algebraic_set,
+		   Response& algebraic_response)
+{
+#ifdef HAVE_AMPL
+  // make sure cur_ASL is pointing to the ASL of this interface
+  // this is important for problems with multiple interfaces
+  set_cur_ASL(asl);
+  const ShortArray& algebraic_asv = algebraic_set.request_vector();
+  const SizetArray& algebraic_dvv = algebraic_set.derivative_vector();
+  size_t i, num_alg_fns = algebraic_asv.size(),
+    num_alg_vars = algebraic_dvv.size();
+  bool grad_flag = false, hess_flag = false;
+  for (i=0; i<num_alg_fns; ++i) {
+    if (algebraic_asv[i] & 2)
+      grad_flag = true;
+    if (algebraic_asv[i] & 4)
+      hess_flag = true;
+  }
+
+  // dak_a_c_vars (DAKOTA space) -> nl_vars (reduced AMPL space)
+  const RealVector& dak_a_c_vars = vars.all_continuous_variables();
+  //IntVector  dak_a_d_vars = vars.all_discrete_variables();
+  Real* nl_vars = new Real [num_alg_vars];
+  for (i=0; i<num_alg_vars; i++)
+    nl_vars[i] = dak_a_c_vars[algebraicACVIndices[i]];
+
+  // nl_vars -> algebraic_response
+  algebraic_response.reset_inactive(); // zero inactive data
+  Real fn_val; RealVector fn_grad; RealSymMatrix fn_hess;
+  fint err = 0;
+  for (i=0; i<num_alg_fns; i++) {
+    // nl_vars -> response fns via AMPL
+    if (algebraic_asv[i] & 1) {
+      if (algebraicFnTypes[i] > 0)
+	fn_val = objval(algebraicFnTypes[i]-1, nl_vars, &err);
+      else
+	fn_val = conival(-1-algebraicFnTypes[i], nl_vars, &err);
+      if (err) {
+	Cerr << "\nError: AMPL processing failure in objval().\n" << std::endl;
+	abort_handler(INTERFACE_ERROR);
+      }
+      algebraic_response.function_value(fn_val, i);
+    }
+    // nl_vars -> response grads via AMPL
+    if (algebraic_asv[i] & 6) { // need grad for Hessian
+      fn_grad = algebraic_response.function_gradient_view(i);
+      if (algebraicFnTypes[i] > 0)
+	objgrd(algebraicFnTypes[i]-1, nl_vars, fn_grad.values(), &err);
+      else
+	congrd(-1-algebraicFnTypes[i], nl_vars, fn_grad.values(), &err);
+      if (err) {
+	Cerr << "\nError: AMPL processing failure in objgrad().\n" << std::endl;
+	abort_handler(INTERFACE_ERROR);
+      }
+    }
+    // nl_vars -> response Hessians via AMPL
+    if (algebraic_asv[i] & 4) {
+      fn_hess = algebraic_response.function_hessian_view(i);
+      // the fullhess calls must follow corresp call to objgrad/congrad
+      if (algebraicFnTypes[i] > 0)
+	fullhes(fn_hess.values(), num_alg_vars, algebraicFnTypes[i]-1,
+		NULL, NULL);
+      else {
+	algebraicConstraintWeights.assign(algebraicConstraintWeights.size(), 0);
+	algebraicConstraintWeights[-1-algebraicFnTypes[i]] = 1;
+	fullhes(fn_hess.values(), num_alg_vars, num_alg_vars, NULL,
+		&algebraicConstraintWeights[0]);
+      }
+    }
+  }
+  delete [] nl_vars;
+  algebraic_response.function_labels(algebraicFnTags);
+#ifdef DEBUG
+  Cout << ">>>>> algebraic_response.fn_labels\n"
+       << algebraic_response.function_labels() << std::endl;
+#endif // DEBUG
+
+  if (outputLevel > NORMAL_OUTPUT)
+    Cout << "Algebraic mapping applied.\n";
+#endif // HAVE_AMPL
+}
+
+
+/** This function will get invoked even when only algebraic mappings are
+    active (no core mappings from derived_map), since the AMPL
+    algebraic_response may be ordered differently from the total_response.
+    In this case, the core_response object is unused. */
+void Interface::
+response_mapping(const Response& algebraic_response,
+		 const Response& core_response, Response& total_response)
+{
+  const ShortArray& total_asv = total_response.active_set_request_vector();
+  const SizetArray& total_dvv = total_response.active_set_derivative_vector();
+  size_t i, j, k, num_total_fns = total_asv.size(),
+    num_total_vars = total_dvv.size();
+  bool grad_flag = false, hess_flag = false;
+  for (i=0; i<num_total_fns; ++i) {
+    if (total_asv[i] & 2)
+      grad_flag = true;
+    if (total_asv[i] & 4)
+      hess_flag = true;
+  }
+
+  // core_response contributions to total_response:
+
+  if (coreMappings) {
+    total_response.reset_inactive();
+    const ShortArray& core_asv = core_response.active_set_request_vector();
+    size_t num_core_fns = core_asv.size();
+    for (i=0; i<num_core_fns; ++i) {
+      if (core_asv[i] & 1)
+	total_response.function_value(core_response.function_value(i), i);
+      if (core_asv[i] & 2)
+	total_response.function_gradient(
+	  core_response.function_gradient_view(i), i);
+      if (core_asv[i] & 4)
+	total_response.function_hessian(core_response.function_hessian(i), i);
+    }
+  }
+  else {
+    // zero all response data before adding algebraic data to it
+    total_response.reset();
+  }
+
+  // algebraic_response contributions to total_response:
+
+  const ShortArray& algebraic_asv
+    = algebraic_response.active_set_request_vector();
+  size_t num_alg_fns = algebraic_asv.size(),
+    num_alg_vars = algebraic_response.active_set_derivative_vector().size();
+  if (num_alg_fns > num_total_fns) {
+    Cerr << "Error: response size mismatch in Interface::response_mapping()."
+	 << std::endl;
+    abort_handler(-1);
+  }
+  if ( (grad_flag || hess_flag) && num_alg_vars > num_total_vars) {
+    Cerr << "Error: derivative variables size mismatch in Interface::"
+         << "response_mapping()." << std::endl;
+    abort_handler(-1);
+  }
+  SizetArray algebraic_dvv_indices;
+  if (grad_flag || hess_flag) {
+    algebraic_dvv_indices.resize(num_alg_vars);
+    using Pecos::find_index;
+    for (i=0; i<num_alg_vars; ++i)
+      algebraic_dvv_indices[i] = find_index(total_dvv, algebraicACVIds[i]);
+      // Note: _NPOS return is handled below
+  }
+  // augment total_response
+  const RealVector& algebraic_fn_vals = algebraic_response.function_values();
+  const RealMatrix& algebraic_fn_grads
+    = algebraic_response.function_gradients();
+  const RealSymMatrixArray& algebraic_fn_hessians
+    = algebraic_response.function_hessians();
+  RealVector total_fn_vals = total_response.function_values_view();
+  for (i=0; i<num_alg_fns; ++i) {
+    size_t fn_index = algebraicFnIndices[i];
+    if (algebraic_asv[i] & 1)
+      total_fn_vals[fn_index] += algebraic_fn_vals[i];
+    if (algebraic_asv[i] & 2) {
+      const Real* algebraic_fn_grad = algebraic_fn_grads[i];
+      RealVector total_fn_grad
+	= total_response.function_gradient_view(fn_index);
+      for (j=0; j<num_alg_vars; j++) {
+	size_t dvv_index = algebraic_dvv_indices[j];
+	if (dvv_index != _NPOS)
+	  total_fn_grad[dvv_index] += algebraic_fn_grad[j];
+      }
+    }
+    if (algebraic_asv[i] & 4) {
+      const RealSymMatrix& algebraic_fn_hess = algebraic_fn_hessians[i];
+      RealSymMatrix total_fn_hess
+	= total_response.function_hessian_view(fn_index);
+      for (j=0; j<num_alg_vars; ++j) {
+	size_t dvv_index_j = algebraic_dvv_indices[j];
+	if (dvv_index_j != _NPOS) {
+	  for (k=0; k<=j; ++k) {
+	    size_t dvv_index_k = algebraic_dvv_indices[k];
+	    if (dvv_index_k != _NPOS)
+	      total_fn_hess(dvv_index_j,dvv_index_k) +=	algebraic_fn_hess(j,k);
+	  }
+	}
+      }
+    }
+  }
+
+  // output response sets:
+
+  if (outputLevel == DEBUG_OUTPUT) {
+    if (coreMappings) Cout << "core_response:\n" << core_response;
+    Cout << "algebraic_response:\n" << algebraic_response
+	 << "total_response:\n"     << total_response << '\n';
+  }
+}
+
+
+String Interface::final_eval_id_tag(int iface_eval_id)
+{
+  if (interfaceRep)
+    return interfaceRep->final_eval_id_tag(iface_eval_id);
+
+  if (appendIfaceId)
+    return evalTagPrefix + "." + boost::lexical_cast<std::string>(iface_eval_id);
+  return evalTagPrefix;
+}
+
+
+int Interface::algebraic_function_type(String functionTag)
+{
+#ifdef HAVE_AMPL
+  int i;
+  for (i=0; i<n_obj; i++)
+    if (strcontains(functionTag, obj_name(i)))
+      return i+1;
+  for (i=0; i<n_con; i++)
+    if (strcontains(functionTag, con_name(i)))
+      return -(i+1);
+
+  Cerr << "Error: No function type available for \'" << functionTag << "\' "
+       << "via algebraic_mappings interface." << std::endl;
+  abort_handler(INTERFACE_ERROR);
+#else
+  return 0;
+#endif // HAVE_AMPL
+}
+
+const IntResponseMap& Interface::synch()
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual synch function.\n"
+         << "No default synch defined at Interface base class." << std::endl;
+    abort_handler(-1);
+  }
+
+  return interfaceRep->synch();
+}
+
+
+const IntResponseMap& Interface::synch_nowait()
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual synch_nowait "
+	 << "function.\nNo default synch_nowait defined at Interface base "
+	 << "class." << std::endl;
+    abort_handler(-1);
+  }
+
+  return interfaceRep->synch_nowait();
+}
+
+
+void Interface::serve_evaluations()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->serve_evaluations();
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual serve_evaluations "
+	 << "function.\nNo default serve_evaluations defined at Interface"
+	 << " base class." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::stop_evaluation_servers()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->stop_evaluation_servers();
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual stop_evaluation_"
+	 << "servers fn.\nNo default stop_evaluation_servers defined at "
+	 << "Interface base class." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::init_communicators(const IntArray& message_lengths,
+				   int max_eval_concurrency)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->init_communicators(message_lengths, max_eval_concurrency);
+  else { // letter lacking redefinition of virtual fn.
+    // ApproximationInterfaces: do nothing
+  }
+}
+
+
+void Interface::set_communicators(const IntArray& message_lengths,
+				  int max_eval_concurrency)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->set_communicators(message_lengths, max_eval_concurrency);
+  else { // letter lacking redefinition of virtual fn.
+    // ApproximationInterfaces: do nothing
+  }
+}
+
+
+/*
+void Interface::free_communicators()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->free_communicators();
+  else { // letter lacking redefinition of virtual fn.
+    // default is no-op
+  }
+}
+*/
+
+
+void Interface::init_serial()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->init_serial();
+  else { // letter lacking redefinition of virtual fn.
+    // ApproximationInterfaces: do nothing
+  }
+}
+
+
+int Interface::asynch_local_evaluation_concurrency() const
+{
+  if (interfaceRep) // envelope fwd to letter
+    return interfaceRep->asynch_local_evaluation_concurrency();
+  else // letter lacking redefinition of virtual fn.
+    return 0; // default (redefined only for ApplicationInterfaces)
+}
+
+
+short Interface::interface_synchronization() const
+{
+  if (interfaceRep) // envelope fwd to letter
+    return interfaceRep->interface_synchronization(); // ApplicationInterfaces
+  else // letter lacking redefinition of virtual fn.
+    return SYNCHRONOUS_INTERFACE; // default (ApproximationInterfaces)
+}
+
+
+int Interface::minimum_points(bool constraint_flag) const
+{
+  if (interfaceRep) // envelope fwd to letter
+    return interfaceRep->minimum_points(constraint_flag);
+  else // letter lacking redefinition of virtual fn.
+    return 0; // default (currently redefined only for ApproximationInterfaces)
+}
+
+
+int Interface::recommended_points(bool constraint_flag) const
+{
+  if (interfaceRep) // envelope fwd to letter
+    return interfaceRep->recommended_points(constraint_flag);
+  else // letter lacking redefinition of virtual fn.
+    return 0; // default (currently redefined only for ApproximationInterfaces)
+}
+
+
+void Interface::approximation_function_indices(const IntSet& approx_fn_indices)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->approximation_function_indices(approx_fn_indices);
+  // else: default implementation is no-op
+}
+
+
+void Interface::
+update_approximation(const Variables& vars, const IntResponsePair& response_pr)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->update_approximation(vars, response_pr);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual update_approximation"
+         << "(Variables, IntResponsePair) function.\n       This interface "
+	 << "does not support approximation updating." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+update_approximation(const RealMatrix& samples, const IntResponseMap& resp_map)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->update_approximation(samples, resp_map);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual update_approximation"
+         << "(RealMatrix, IntResponseMap) function.\n       This interface "
+	 << "does not support approximation updating." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+update_approximation(const VariablesArray& vars_array,
+		     const IntResponseMap& resp_map)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->update_approximation(vars_array, resp_map);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual update_approximation"
+         << "(VariablesArray, IntResponseMap) function.\n       This interface "
+	 << "does not support approximation updating." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+append_approximation(const Variables& vars, const IntResponsePair& response_pr)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->append_approximation(vars, response_pr);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual append_approximation"
+	 << "(Variables, IntResponsePair) function.\n       This interface "
+	 << "does not support approximation appending." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+append_approximation(const RealMatrix& samples, const IntResponseMap& resp_map)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->append_approximation(samples, resp_map);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual append_approximation"
+         << "(RealMatrix, IntResponseMap) function.\n       This interface "
+	 << "does not support approximation appending." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+append_approximation(const VariablesArray& vars_array,
+		     const IntResponseMap& resp_map)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->append_approximation(vars_array, resp_map);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual append_approximation"
+         << "(VariablesArray, IntResponseMap) function.\n       This interface "
+	 << "does not support approximation appending." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+build_approximation(const RealVector&  c_l_bnds, const RealVector&  c_u_bnds,
+		    const IntVector&  di_l_bnds, const IntVector&  di_u_bnds,
+		    const RealVector& dr_l_bnds, const RealVector& dr_u_bnds)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->build_approximation(c_l_bnds, c_u_bnds, di_l_bnds, di_u_bnds,
+				      dr_l_bnds, dr_u_bnds);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual build_approximation"
+         << "() function.\n       This interface does not support "
+	 << "approximations." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::
+rebuild_approximation(const BoolDeque& rebuild_deque)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->rebuild_approximation(rebuild_deque);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual rebuild_"
+	 << "approximation() function.\n       This interface does not "
+	 << "support approximations." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::pop_approximation(bool save_surr_data)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->pop_approximation(save_surr_data);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual pop_approximation"
+	 << "(bool)\n       function. This interface does not support "
+	 << "approximation\n       data removal." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::restore_approximation()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->restore_approximation();
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual restore_"
+	 << "approximation() function.\n       This interface does not "
+	 << "support approximation restoration." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+bool Interface::restore_available()
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual restore_"
+	 << "available() function.\n       This interface does not "
+	 << "support approximation restoration queries." << std::endl;
+    abort_handler(-1);
+  }
+  return interfaceRep->restore_available();
+}
+
+
+void Interface::finalize_approximation()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->finalize_approximation();
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual finalize_"
+	 << "approximation() function.\n       This interface does not "
+	 << "support approximation finalization." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::store_approximation()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->store_approximation();
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual store_"
+	 << "approximation() function.\n       This interface does not "
+	 << "support approximation storage." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::combine_approximation(short corr_type)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->combine_approximation(corr_type);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual combine_"
+	 << "approximation() function.\n       This interface does not "
+	 << "support approximation combination." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+void Interface::clear_current()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->clear_current();
+  else { // letter lacking redefinition of virtual fn.
+    // ApplicationInterfaces: do nothing
+  }
+}
+
+
+void Interface::clear_all()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->clear_all();
+  else { // letter lacking redefinition of virtual fn.
+    // ApplicationInterfaces: do nothing
+  }
+}
+
+
+void Interface::clear_saved()
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->clear_saved();
+  else { // letter lacking redefinition of virtual fn.
+    // ApplicationInterfaces: do nothing
+  }
+}
+
+
+SharedApproxData& Interface::shared_approximation()
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual shared_approximation"
+         << "() function.\nThis interface does not support approximations."
+	 << std::endl;
+    abort_handler(-1);
+  }
+
+  // envelope fwd to letter
+  return interfaceRep->shared_approximation();
+}
+
+
+std::vector<Approximation>& Interface::approximations()
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual approximations() "
+	 << "function.\n       This interface does not support approximations."
+	 << std::endl;
+    abort_handler(-1);
+  }
+
+  // envelope fwd to letter
+  return interfaceRep->approximations();
+}
+
+
+const Pecos::SurrogateData& Interface::approximation_data(size_t index)
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual approximation_data "
+	 << "function.\n       This interface does not support approximations."
+	 << std::endl;
+    abort_handler(-1);
+  }
+
+  // envelope fwd to letter
+  return interfaceRep->approximation_data(index);
+}
+
+
+const RealVectorArray& Interface::approximation_coefficients(bool normalized)
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual approximation_"
+	 << "coefficients function.\n       This interface does not support "
+         << "approximations." << std::endl;
+    abort_handler(-1);
+  }
+
+  // envelope fwd to letter
+  return interfaceRep->approximation_coefficients(normalized);
+}
+
+
+void Interface::
+approximation_coefficients(const RealVectorArray& approx_coeffs,
+			   bool normalized)
+{
+  if (interfaceRep) // envelope fwd to letter
+    interfaceRep->approximation_coefficients(approx_coeffs, normalized);
+  else { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual approximation_"
+	 << "coefficients function.\n       This interface does not support "
+         << "approximations." << std::endl;
+    abort_handler(-1);
+  }
+}
+
+
+const RealVector& Interface::approximation_variances(const Variables& vars)
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual approximation_"
+	 << "variances function.\n       This interface does not support "
+         << "approximations." << std::endl;
+    abort_handler(-1);
+  }
+
+  // envelope fwd to letter
+  return interfaceRep->approximation_variances(vars);
+}
+
+
+const StringArray& Interface::analysis_drivers() const
+{
+  if (!interfaceRep) { // letter lacking redefinition of virtual fn.
+    Cerr << "Error: Letter lacking redefinition of virtual analysis_drivers "
+	 << "function." << std::endl;
+    abort_handler(-1);
+  }
+
+  // envelope fwd to letter
+  return interfaceRep->analysis_drivers();
+}
+
+
+bool Interface::evaluation_cache() const
+{
+  if (interfaceRep)
+    return interfaceRep->evaluation_cache();
+  else // letter lacking redefinition of virtual fn.
+    return false; // default
+}
+
+
+void Interface::file_cleanup() const
+{
+  if (interfaceRep)
+    interfaceRep->file_cleanup();
+  // else no-op
+}
+
+} // namespace Dakota
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/NonDLocalReliability.cpp
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/NonDLocalReliability.cpp	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/NonDLocalReliability.cpp	(revision 24593)
@@ -0,0 +1,2704 @@
+/*  _______________________________________________________________________
+
+    DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
+    Copyright 2014 Sandia Corporation.
+    This software is distributed under the GNU Lesser General Public License.
+    For more information, see the README file in the top Dakota directory.
+    _______________________________________________________________________ */
+
+//- Class:	 NonDLocalReliability
+//- Description: Implementation code for NonDLocalReliability class
+//- Owner:       Mike Eldred
+//- Checked by:
+//- Version:
+
+#include "dakota_system_defs.hpp"
+#include "DakotaResponse.hpp"
+#include "ParamResponsePair.hpp"
+#include "PRPMultiIndex.hpp"
+#include "ProblemDescDB.hpp"
+#include "DakotaGraphics.hpp"
+#include "NonDLocalReliability.hpp"
+#include "NonDAdaptImpSampling.hpp"
+#ifdef HAVE_NPSOL
+#include "NPSOLOptimizer.hpp"
+#endif
+#ifdef HAVE_OPTPP
+#include "SNLLOptimizer.hpp"
+using OPTPP::NLPFunction;
+using OPTPP::NLPGradient;
+#endif
+#include "RecastModel.hpp"
+#include "DataFitSurrModel.hpp"
+#include "NestedModel.hpp"
+#include "Teuchos_LAPACK.hpp"
+#include "Teuchos_SerialDenseHelpers.hpp"
+#include <algorithm>
+#include "dakota_data_io.hpp"
+
+//#define MPP_CONVERGE_RATE
+//#define DEBUG
+
+static const char rcsId[] = "@(#) $Id: NonDLocalReliability.cpp 4058 2006-10-25 01:39:40Z mseldre $";
+
+namespace Dakota {
+extern PRPCache data_pairs; // global container
+
+
+// define special values for componentParallelMode
+//#define SURROGATE_MODEL 1
+#define TRUTH_MODEL 2
+
+
+// initialization of statics
+NonDLocalReliability* NonDLocalReliability::nondLocRelInstance(NULL);
+
+
+NonDLocalReliability::
+NonDLocalReliability(ProblemDescDB& problem_db, Model& model):
+  NonDReliability(problem_db, model),
+  initialPtUserSpec(
+    probDescDB.get_bool("variables.uncertain.initial_point_flag")),
+  warmStartFlag(true), nipModeOverrideFlag(true),
+  curvatureDataAvailable(false), kappaUpdated(false),
+  secondOrderIntType(HOHENRACK), curvatureThresh(1.e-10), warningBits(0)
+{
+  // check for suitable gradient and variables specifications
+  if (iteratedModel.gradient_type() == "none") {
+    Cerr << "\nError: local_reliability requires a gradient specification."
+	 << std::endl;
+    abort_handler(-1);
+  }
+  if (numEpistemicUncVars) {
+    Cerr << "Error: epistemic variables are not supported in local "
+	 << "reliability methods." << std::endl;
+    abort_handler(-1);
+  }
+
+  if (mppSearchType) { // default is MV = 0
+
+    // Map MPP search NIP/SQP algorithm specification into an NPSOL/OPT++
+    // selection based on configuration availability.
+#if !defined(HAVE_NPSOL) && !defined(HAVE_OPTPP)
+    Cerr << "Error: this executable not configured with NPSOL or OPT++.\n"
+	 << "       NonDLocalReliability cannot perform MPP search."
+         << std::endl;
+    abort_handler(-1);
+#endif
+    unsigned short mpp_optimizer = probDescDB.get_ushort("method.sub_method");
+    if (mpp_optimizer == SUBMETHOD_SQP) {
+#ifdef HAVE_NPSOL
+      npsolFlag = true;
+#else
+      Cerr << "\nError: this executable not configured with NPSOL SQP.\n"
+	   << "         Please select OPT++ NIP within local_reliability."
+	   << std::endl;
+      abort_handler(-1);
+#endif
+    }
+    else if (mpp_optimizer == SUBMETHOD_NIP) {
+#ifdef HAVE_OPTPP
+      npsolFlag = false;
+#else
+      Cerr << "\nError: this executable not configured with OPT++ NIP.\n"
+	   << "         please select NPSOL SQP within local_reliability."
+	   << std::endl;
+      abort_handler(-1);
+#endif
+    }
+    else if (mpp_optimizer == SUBMETHOD_DEFAULT) {
+#ifdef HAVE_NPSOL
+      npsolFlag = true;
+#elif HAVE_OPTPP
+      npsolFlag = false;
+#endif
+    }
+
+    // Error check for a specification of at least 1 level for MPP methods
+    if (!totalLevelRequests) {
+      Cerr << "\nError: An MPP search method requires the specification of at "
+	   << "least one response, probability, or reliability level."
+	   << std::endl;
+      abort_handler(-1);
+    }
+  }
+
+  // Prevent nesting of an instance of a Fortran iterator within another
+  // instance of the same iterator (which would result in data clashes since
+  // Fortran does not support object independence).  Recurse through all
+  // sub-models and test each sub-iterator for SOL presence.
+  // Note 1: This check is performed for DOT, CONMIN, and SOLBase, but not
+  //         for LHS since it is only active in pre-processing.
+  // Note 2: NPSOL/NLSSOL on the outer loop with NonDLocalReliability on the
+  //         inner loop precludes all NPSOL-based MPP searches;
+  //         NonDLocalReliability on the outer loop with NPSOL/NLSSOL on an
+  //         inner loop is only a problem for the no_approx MPP search (since
+  //         iteratedModel is not invoked w/i an approx-based MPP search).
+  if (mppSearchType == NO_APPROX && npsolFlag) {
+    Iterator sub_iterator = iteratedModel.subordinate_iterator();
+    if (!sub_iterator.is_null() &&
+	( sub_iterator.method_name() ==  NPSOL_SQP ||
+	  sub_iterator.method_name() == NLSSOL_SQP ||
+	  sub_iterator.uses_method() ==  NPSOL_SQP ||
+	  sub_iterator.uses_method() == NLSSOL_SQP ) )
+      sub_iterator.method_recourse();
+    ModelList& sub_models = iteratedModel.subordinate_models();
+    for (ModelLIter ml_iter = sub_models.begin();
+	 ml_iter != sub_models.end(); ml_iter++) {
+      sub_iterator = ml_iter->subordinate_iterator();
+      if (!sub_iterator.is_null() &&
+	  ( sub_iterator.method_name() ==  NPSOL_SQP ||
+	    sub_iterator.method_name() == NLSSOL_SQP ||
+	    sub_iterator.uses_method() ==  NPSOL_SQP ||
+	    sub_iterator.uses_method() == NLSSOL_SQP ) )
+	sub_iterator.method_recourse();
+    }
+  }
+
+  // Map response Hessian specification into taylorOrder for use by MV/AMV/AMV+
+  // variants.  Note that taylorOrder and integrationOrder are independent
+  // (although the Hessian specification required for 2nd-order integration
+  // means that taylorOrder = 2 will be used for MV/AMV/AMV+; taylorOrder = 2
+  // may however be used with 1st-order integration).
+  const String& hess_type = iteratedModel.hessian_type();
+  taylorOrder = (hess_type != "none" && mppSearchType <= AMV_PLUS_U) ? 2 : 1;
+
+  // assign iterator-specific defaults for approximation-based MPP searches
+  if (maxIterations <  0          && // DataMethod default = -1
+      mppSearchType >= AMV_PLUS_X && mppSearchType < NO_APPROX) // approx-based
+    maxIterations = 25;
+
+  // The model of the limit state in u-space (uSpaceModel) is constructed here
+  // one time.  The RecastModel for the RIA/PMA formulations varies with the
+  // level requests and is constructed for each level within mpp_search().
+
+  // Instantiate the Nataf Recast and any DataFit model recursions.  Recast is
+  // bounded to 10 std devs in u space.  This is particularly important for PMA
+  // since an SQP-based optimizer will not enforce the constraint immediately
+  // and min +/-g has been observed to have significant excursions early on
+  // prior to the u'u = beta^2 constraint enforcement bringing it back.  A
+  // large excursion can cause overflow; a medium excursion can cause poor
+  // performance since far-field info is introduced into the BFGS Hessian.
+  if (mppSearchType ==  AMV_X || mppSearchType == AMV_PLUS_X ||
+      mppSearchType == TANA_X) { // Recast( DataFit( iteratedModel ) )
+
+    // Construct g-hat(x) using a local/multipoint approximation over the
+    // uncertain variables (using the same view as iteratedModel).
+    Model g_hat_x_model;
+    String sample_reuse, approx_type = (mppSearchType == TANA_X) ?
+      "multipoint_tana" : "local_taylor";
+    UShortArray approx_order(1, taylorOrder);
+    short corr_order = -1, corr_type = NO_CORRECTION,
+      data_order = (taylorOrder == 2) ? 7 : 3;
+    int samples = 0, seed = 0;
+    Iterator dace_iterator;
+    //const Variables& curr_vars = iteratedModel.current_variables();
+    ActiveSet surr_set = iteratedModel.current_response().active_set(); // copy
+    surr_set.request_values(3); // surrogate gradient evals
+    g_hat_x_model.assign_rep(new DataFitSurrModel(dace_iterator, iteratedModel,
+      surr_set, approx_type, approx_order, corr_type, corr_order, data_order,
+      outputLevel, sample_reuse), false);
+
+    // transform g_hat_x_model from x-space to u-space
+    transform_model(g_hat_x_model, uSpaceModel, true); // globally bounded
+  }
+  else if (mppSearchType ==  AMV_U || mppSearchType == AMV_PLUS_U ||
+	   mppSearchType == TANA_U) { // DataFit( Recast( iteratedModel ) )
+
+    // Recast g(x) to G(u)
+    Model g_u_model;
+    transform_model(iteratedModel, g_u_model, true); // globally bounded
+
+    // Construct G-hat(u) using a local/multipoint approximation over the
+    // uncertain variables (using the same view as iteratedModel/g_u_model).
+    String sample_reuse, approx_type = (mppSearchType == TANA_U) ?
+      "multipoint_tana" : "local_taylor";
+    UShortArray approx_order(1, taylorOrder);
+    short corr_order = -1, corr_type = NO_CORRECTION,
+      data_order = (taylorOrder == 2) ? 7 : 3;
+    int samples = 0, seed = 0;
+    Iterator dace_iterator;
+    //const Variables& g_u_vars = g_u_model.current_variables();
+    ActiveSet surr_set = g_u_model.current_response().active_set(); // copy
+    surr_set.request_values(3); // surrogate gradient evals
+    uSpaceModel.assign_rep(new DataFitSurrModel(dace_iterator, g_u_model,
+      surr_set, approx_type, approx_order, corr_type, corr_order, data_order,
+      outputLevel, sample_reuse), false);
+  }
+  else if (mppSearchType == NO_APPROX) // Recast( iteratedModel )
+    // Recast g(x) to G(u)
+    transform_model(iteratedModel, uSpaceModel, true); // globally bounded
+
+  // configure a RecastModel with one objective and one equality constraint
+  // using the alternate minimalist constructor
+  if (mppSearchType) {
+    SizetArray recast_vars_comps_total;  // default: empty; no change in size
+    BitArray all_relax_di, all_relax_dr; // default: empty; no discrete relax
+    mppModel.assign_rep(
+      new RecastModel(uSpaceModel, recast_vars_comps_total,
+		      all_relax_di, all_relax_dr, 1, 1, 0), false);
+    RealVector nln_eq_targets(1, false); nln_eq_targets = 0.;
+    mppModel.nonlinear_eq_constraint_targets(nln_eq_targets);
+
+    // Use NPSOL/OPT++ in "user_functions" mode to perform the MPP search
+    if (npsolFlag) {
+      // NPSOL deriv level: 1 = supplied grads of objective fn, 2 = supplied
+      // grads of constraints, 3 = supplied grads of both.  Always use the
+      // supplied grads of u'u (deriv level = 1 for RIA, deriv level = 2 for
+      // PMA).  In addition, use supplied gradients of G(u) in most cases.
+      // Exception: deriv level = 3 results in a gradient-based line search,
+      // which could be too expensive for FORM with numerical grads unless
+      // seeking parallel load balance.
+      //int npsol_deriv_level;
+      //if ( mppSearchType == NO_APPROX && !iteratedModel.asynch_flag()
+      //     && iteratedModel.gradient_type() != "analytic" )
+      //  npsol_deriv_level = (ria_flag) ? 1 : 2;
+      //else
+      //  npsol_deriv_level = 3;
+      //Cout << "Derivative level = " << npsol_deriv_level << '\n';
+
+      // The gradient-based line search (deriv. level = 3) appears to be
+      // outperforming the value-based line search in PMA testing.  In
+      // addition, the RIA warm start needs fnGradU so deriv. level = 3 has
+      // superior performance there as well.  Therefore, deriv level = 3 can
+      // be used for all cases.
+      int npsol_deriv_level = 3;
+
+      // run a tighter tolerance on approximation-based MPP searches
+      //Real conv_tol = (mppSearchType == NO_APPROX) ? 1.e-4 : 1.e-6;
+      Real conv_tol = -1.; // use NPSOL default
+
+#ifdef HAVE_NPSOL
+      mppOptimizer.assign_rep(new NPSOLOptimizer(mppModel, npsol_deriv_level,
+	conv_tol), false);
+#endif
+    }
+#ifdef HAVE_OPTPP
+    else
+      mppOptimizer.assign_rep(new SNLLOptimizer("optpp_q_newton", mppModel),
+	false);
+#endif
+  }
+
+  // Map integration specification into integrationOrder.  Second-order
+  // integration requires an MPP search in u-space, and is not warranted for
+  // unconverged MPP's (AMV variants).  In addition, AMV variants only compute
+  // verification function values at u* (no Hessians).  For an AMV-like
+  // approach with 2nd-order integration, use AMV+ with max_iterations = 1.
+  const String& integration_method
+    = probDescDB.get_string("method.nond.reliability_integration");
+  if (integration_method.empty() || integration_method == "first_order")
+    integrationOrder = 1;
+  else if (integration_method == "second_order") {
+    if (hess_type == "none") {
+      Cerr << "\nError: second-order integration requires Hessian "
+	   << "specification." << std::endl;
+      abort_handler(-1);
+    }
+    else if (mppSearchType <= AMV_U) {
+      Cerr << "\nError: second-order integration only supported for fully "
+	   << "converged MPP methods." << std::endl;
+      abort_handler(-1);
+    }
+    else
+      integrationOrder = 2;
+  }
+  else {
+    Cerr << "Error: bad integration selection in NonDLocalReliability."
+	 << std::endl;
+    abort_handler(-1);
+  }
+
+  if (integrationRefinement) {
+    for (size_t i=0; i<numFunctions; i++)
+      if (!requestedProbLevels[i].empty() || !requestedRelLevels[i].empty() ||
+	  !requestedGenRelLevels[i].empty()) {
+	Cerr << "\nError: importance sampling methods only supported for RIA."
+	     << "\n\n";
+	abort_handler(-1);
+      }
+    // integration refinement requires an MPP, but it may be unconverged (AMV)
+    if (!mppSearchType) {
+      Cerr << "\nError: integration refinement only supported for MPP methods."
+	   << std::endl;
+      abort_handler(-1);
+    }
+
+    // For NonDLocal, integration refinement is applied to the original model
+    int refine_samples = probDescDB.get_int("method.nond.refinement_samples"),
+        refine_seed    = probDescDB.get_int("method.random_seed");
+    if (!refine_samples) refine_samples = 1000; // context-specific default
+
+    unsigned short sample_type = SUBMETHOD_DEFAULT;
+    String rng; // empty string: use default
+
+    // Note: global bounds definition in transform_model() can be true
+    // (to bound an optimizer search) with AIS use_model_bounds = false
+    // (AIS will ignore these global bounds).
+    bool x_model_flag = false, use_model_bounds = false, vary_pattern = true;
+
+    // AIS is performed in u-space WITHOUT a surrogate: pass a truth u-space
+    // model when available, construct one when not.
+    switch (mppSearchType) {
+    case AMV_X: case AMV_PLUS_X: case TANA_X: {
+      Model g_u_model;
+      transform_model(iteratedModel, g_u_model); // global bounds not needed
+      importanceSampler.assign_rep(new
+        NonDAdaptImpSampling(g_u_model, sample_type, refine_samples,
+	  refine_seed, rng, vary_pattern, integrationRefinement, cdfFlag,
+	  x_model_flag, use_model_bounds), false);
+      break;
+    }
+    case AMV_U: case AMV_PLUS_U: case TANA_U:
+      importanceSampler.assign_rep(new
+	NonDAdaptImpSampling(uSpaceModel.truth_model(), sample_type,
+	  refine_samples, refine_seed, rng, vary_pattern, integrationRefinement,
+	  cdfFlag, x_model_flag, use_model_bounds), false);
+      break;
+    case NO_APPROX:
+      importanceSampler.assign_rep(new
+        NonDAdaptImpSampling(uSpaceModel, sample_type, refine_samples,
+	  refine_seed, rng, vary_pattern, integrationRefinement, cdfFlag,
+	  x_model_flag, use_model_bounds), false);
+      break;
+    }
+  }
+
+  // Size the output arrays.  Relative to sampling methods, the output storage
+  // for reliability methods is more substantial since there may be differences
+  // between requested and computed levels for the same measure (the request is
+  // not always achieved) and since probability and reliability are carried
+  // along in parallel (due to their direct correspondence).
+  computedRelLevels.resize(numFunctions);
+  for (size_t i=0; i<numFunctions; i++) {
+    size_t num_levels = requestedRespLevels[i].length() +
+      requestedProbLevels[i].length() + requestedRelLevels[i].length() +
+      requestedGenRelLevels[i].length();
+    computedRespLevels[i].resize(num_levels);
+    computedProbLevels[i].resize(num_levels);
+    computedRelLevels[i].resize(num_levels);
+    computedGenRelLevels[i].resize(num_levels);
+  }
+
+  // Size class-scope arrays.
+  mostProbPointX.sizeUninitialized(numUncertainVars);
+  mostProbPointU.sizeUninitialized(numUncertainVars);
+  fnGradX.sizeUninitialized(numUncertainVars);
+  fnGradU.sizeUninitialized(numUncertainVars);
+  if (taylorOrder == 2 || integrationOrder == 2) {
+    fnHessX.shapeUninitialized(numUncertainVars);
+    fnHessU.shapeUninitialized(numUncertainVars);
+    if (hess_type == "quasi") {
+      // Note: fnHess=0 in both spaces is not self-consistent for nonlinear
+      // transformations.  However, the point is to use a first-order
+      // approximation in either space prior to curvature accumulation.
+      fnHessX = 0.;
+      fnHessU = 0.;
+    }
+    kappaU.sizeUninitialized(numUncertainVars-1);
+  }
+}
+
+
+NonDLocalReliability::~NonDLocalReliability()
+{ }
+
+
+void NonDLocalReliability::derived_init_communicators(ParLevLIter pl_iter)
+{
+  iteratedModel.init_communicators(pl_iter, maxEvalConcurrency);
+  if (mppSearchType) {
+    // uSpaceModel, mppOptimizer, and importanceSampler use NoDBBaseConstructor,
+    // so no need to manage DB list nodes at this level
+
+    // maxEvalConcurrency defined from the derivative concurrency in the
+    // responses specification.  For FORM/SORM, the NPSOL/OPT++ concurrency
+    // is the same, but for approximate methods, the concurrency is dictated
+    // by the gradType/hessType logic in the instantiate on-the-fly
+    // DataFitSurrModel constructor.
+    uSpaceModel.init_communicators(pl_iter, maxEvalConcurrency);
+    // TO DO: distinguish gradient concurrency for truth vs. surrogate?
+    //        (probably doesn't matter for surrogate)
+
+    mppOptimizer.init_communicators(pl_iter);
+
+    if (integrationRefinement)
+      importanceSampler.init_communicators(pl_iter);
+  }
+}
+
+
+void NonDLocalReliability::derived_set_communicators(ParLevLIter pl_iter)
+{
+  NonD::derived_set_communicators(pl_iter);
+
+  if (mppSearchType) {
+    uSpaceModel.set_communicators(pl_iter, maxEvalConcurrency);
+    mppOptimizer.set_communicators(pl_iter);
+    if (integrationRefinement)
+      importanceSampler.set_communicators(pl_iter);
+  }
+}
+
+
+void NonDLocalReliability::derived_free_communicators(ParLevLIter pl_iter)
+{
+  if (mppSearchType) {
+    if (integrationRefinement)
+      importanceSampler.free_communicators(pl_iter);
+    mppOptimizer.free_communicators(pl_iter);
+    uSpaceModel.free_communicators(pl_iter, maxEvalConcurrency);
+  }
+  iteratedModel.free_communicators(pl_iter, maxEvalConcurrency);
+}
+
+
+void NonDLocalReliability::quantify_uncertainty()
+{
+  if (mppSearchType) mpp_search();
+  else               mean_value();
+
+  numRelAnalyses++;
+}
+
+
+void NonDLocalReliability::mean_value()
+{
+  // For MV, compute approximate mean, standard deviation, and requested
+  // CDF/CCDF data points for each response function and store in
+  // finalStatistics.  Additionally, if uncorrelated variables, compute
+  // importance factors.
+
+  initialize_random_variable_parameters();
+  initial_taylor_series();
+
+  // initialize arrays
+  impFactor.shapeUninitialized(numUncertainVars, numFunctions);
+  statCount = 0;
+  initialize_final_statistics_gradients();
+
+  // local reliability data aren't output to tabular, so send directly
+  // to graphics window only
+  Graphics& dakota_graphics = parallelLib.output_manager().graphics();
+
+  // loop over response functions
+  size_t i;
+  const ShortArray& final_asv = finalStatistics.active_set_request_vector();
+  for (respFnCount=0; respFnCount<numFunctions; respFnCount++) {
+    Real& mean    = momentStats(0,respFnCount);
+    Real& std_dev = momentStats(1,respFnCount);
+
+    // approximate response means already computed
+    finalStatistics.function_value(mean, statCount);
+    // sensitivity of response mean
+    if (final_asv[statCount] & 2) {
+      RealVector fn_grad_mean_x(numUncertainVars, false);
+      for (i=0; i<numUncertainVars; i++)
+	fn_grad_mean_x[i] = fnGradsMeanX(i,respFnCount);
+      // evaluate dg/ds at the variable means and store in finalStatistics
+      RealVector final_stat_grad;
+      dg_ds_eval(natafTransform.x_means(), fn_grad_mean_x, final_stat_grad);
+      finalStatistics.function_gradient(final_stat_grad, statCount);
+    }
+    statCount++;
+
+    // approximate response std deviations already computed
+    finalStatistics.function_value(std_dev, statCount);
+    // sensitivity of response std deviation
+    if (final_asv[statCount] & 2) {
+      // Differentiating the first-order second-moment expression leads to
+      // 2nd-order d^2g/dxds sensitivities which would be awkward to compute
+      // (nonstandard DVV containing active and inactive vars)
+      Cerr << "Error: response std deviation sensitivity not yet supported."
+           << std::endl;
+      abort_handler(-1);
+    }
+    statCount++;
+
+    // if inputs are uncorrelated, compute importance factors
+    if (!natafTransform.x_correlation() && std_dev > Pecos::SMALL_NUMBER) {
+      const Pecos::RealVector& x_std_devs = natafTransform.x_std_deviations();
+      for (i=0; i<numUncertainVars; i++)
+        impFactor(i,respFnCount) = std::pow(x_std_devs[i] / std_dev *
+					    fnGradsMeanX(i,respFnCount), 2);
+    }
+
+    // compute probability/reliability levels for requested response levels and
+    // compute response levels for requested probability/reliability levels.
+    // For failure defined as g<0, beta is simply mean/sigma.  This is extended
+    // to compute general cumulative probabilities for g<z or general
+    // complementary cumulative probabilities for g>z.
+    size_t rl_len = requestedRespLevels[respFnCount].length(),
+           pl_len = requestedProbLevels[respFnCount].length(),
+           bl_len = requestedRelLevels[respFnCount].length(),
+           gl_len = requestedGenRelLevels[respFnCount].length();
+    for (levelCount=0; levelCount<rl_len; levelCount++) {
+      // computed = requested in MV case since no validation fn evals
+      Real z = computedRespLevels[respFnCount][levelCount]
+	= requestedRespLevels[respFnCount][levelCount];
+      // compute beta and p from z
+      Real beta, p;
+      if (std_dev > Pecos::SMALL_NUMBER) {
+	Real ratio = (mean - z)/std_dev;
+        beta = computedRelLevels[respFnCount][levelCount]
+	  = computedGenRelLevels[respFnCount][levelCount]
+	  = (cdfFlag) ? ratio : -ratio;
+        p = computedProbLevels[respFnCount][levelCount] = probability(beta);
+      }
+      else {
+        if ( ( cdfFlag && mean <= z) ||
+	     (!cdfFlag && mean >  z) ) {
+          beta = computedRelLevels[respFnCount][levelCount]
+	    = computedGenRelLevels[respFnCount][levelCount]
+	    = -Pecos::LARGE_NUMBER;
+          p = computedProbLevels[respFnCount][levelCount] = 1.;
+	}
+	else {
+          beta = computedRelLevels[respFnCount][levelCount]
+	    = computedGenRelLevels[respFnCount][levelCount]
+	    = Pecos::LARGE_NUMBER;
+          p = computedProbLevels[respFnCount][levelCount] = 0.;
+	}
+      }
+      switch (respLevelTarget) {
+      case PROBABILITIES:
+	finalStatistics.function_value(p, statCount);    break;
+      case RELIABILITIES: case GEN_RELIABILITIES:
+	finalStatistics.function_value(beta, statCount); break;
+      }
+      if (final_asv[statCount] & 2) {
+	Cerr << "Error: response probability/reliability/gen_reliability level "
+	     << "sensitivity not supported for Mean Value." << std::endl;
+	abort_handler(-1);
+      }
+      statCount++;
+      // Update specialty graphics
+      if (!subIteratorFlag)
+	dakota_graphics.add_datapoint(respFnCount, z, p);
+    }
+    for (i=0; i<pl_len; i++) {
+      levelCount = i+rl_len;
+      // computed = requested in MV case since no validation fn evals
+      Real p = computedProbLevels[respFnCount][levelCount]
+	= requestedProbLevels[respFnCount][i];
+      // compute beta and z from p
+      Real beta = computedRelLevels[respFnCount][levelCount]
+	= computedGenRelLevels[respFnCount][levelCount]	= reliability(p);
+      Real z = computedRespLevels[respFnCount][levelCount] = (cdfFlag)
+        ? mean - beta * std_dev : mean + beta * std_dev;
+      finalStatistics.function_value(z, statCount);
+      if (final_asv[statCount] & 2) {
+	Cerr << "Error: response level sensitivity not supported for Mean "
+	     << "Value." << std::endl;
+	abort_handler(-1);
+      }
+      statCount++;
+      // Update specialty graphics
+      if (!subIteratorFlag)
+	dakota_graphics.add_datapoint(respFnCount, z, p);
+    }
+    for (i=0; i<bl_len+gl_len; i++) {
+      levelCount = i+rl_len+pl_len;
+      // computed = requested in MV case since no validation fn evals
+      Real beta = (i<bl_len) ? requestedRelLevels[respFnCount][i] :
+	requestedGenRelLevels[respFnCount][i-bl_len];
+      computedRelLevels[respFnCount][levelCount]
+	= computedGenRelLevels[respFnCount][levelCount] = beta;
+      // compute p and z from beta
+      Real p = computedProbLevels[respFnCount][levelCount] = probability(beta);
+      Real z = computedRespLevels[respFnCount][levelCount] = (cdfFlag)
+        ? mean - beta * std_dev	: mean + beta * std_dev;
+      finalStatistics.function_value(z, statCount);
+      if (final_asv[statCount] & 2) {
+	Cerr << "Error: response level sensitivity not supported for Mean "
+	     << "Value." << std::endl;
+	abort_handler(-1);
+      }
+      statCount++;
+      // Update specialty graphics
+      if (!subIteratorFlag)
+	dakota_graphics.add_datapoint(respFnCount, z, p);
+    }
+  }
+}
+
+
+void NonDLocalReliability::mpp_search()
+{
+  // set the object instance pointer for use within the static member fns
+  NonDLocalReliability* prev_instance = nondLocRelInstance;
+  nondLocRelInstance = this;
+
+  // The following 2 calls must precede use of natafTransform.trans_X_to_U()
+  initialize_random_variable_parameters();
+  // Modify the correlation matrix (Nataf) and compute its Cholesky factor.
+  // Since the uncertain variable distributions (means, std devs, correlations)
+  // may change among NonDLocalReliability invocations (e.g., RBDO with design
+  // variable insertion), this code block is performed on every invocation.
+  transform_correlations();
+
+  // initialize initialPtUSpec on first reliability analysis; needs to precede
+  // iteratedModel.continuous_variables() assignment in initial_taylor_series()
+  if (numRelAnalyses == 0) {
+    if (initialPtUserSpec)
+      natafTransform.trans_X_to_U(iteratedModel.continuous_variables(),
+				  initialPtUSpec);
+    else {
+      // don't use the mean uncertain variable defaults from the parser
+      // since u ~= 0 can cause problems for some formulations
+      initialPtUSpec.sizeUninitialized(numUncertainVars);
+      initialPtUSpec = 1.;
+    }
+  }
+
+  // sets iteratedModel.continuous_variables() to mean values
+  initial_taylor_series();
+
+  // Initialize local arrays
+  statCount = 0;
+  initialize_final_statistics_gradients();
+
+  // Initialize class scope arrays, modify the correlation matrix, and
+  // evaluate median responses
+  initialize_class_data();
+
+  // Loop over each response function in the responses specification.  It is
+  // important to note that the MPP iteration is different for each response
+  // function, and it is not possible to combine the model evaluations for
+  // multiple response functions.
+  size_t i;
+  const ShortArray& final_asv = finalStatistics.active_set_request_vector();
+  for (respFnCount=0; respFnCount<numFunctions; respFnCount++) {
+
+    // approximate response means already computed
+    finalStatistics.function_value(momentStats(0,respFnCount), statCount);
+    // sensitivity of response mean
+    if (final_asv[statCount] & 2) {
+      RealVector fn_grad_mean_x(numUncertainVars, false);
+      for (i=0; i<numUncertainVars; i++)
+	fn_grad_mean_x[i] = fnGradsMeanX(i,respFnCount);
+      // evaluate dg/ds at the variable means and store in finalStatistics
+      RealVector final_stat_grad;
+      dg_ds_eval(natafTransform.x_means(), fn_grad_mean_x, final_stat_grad);
+      finalStatistics.function_gradient(final_stat_grad, statCount);
+    }
+    statCount++;
+
+    // approximate response std deviations already computed
+    finalStatistics.function_value(momentStats(1,respFnCount), statCount);
+    // sensitivity of response std deviation
+    if (final_asv[statCount] & 2) {
+      // Differentiating the first-order second-moment expression leads to
+      // 2nd-order d^2g/dxds sensitivities which would be awkward to compute
+      // (nonstandard DVV containing active and inactive vars)
+      Cerr << "Error: response std deviation sensitivity not yet supported."
+           << std::endl;
+      abort_handler(-1);
+    }
+    statCount++;
+
+    // The most general case is to allow a combination of response, probability,
+    // reliability, and generalized reliability level specifications for each
+    // response function.
+    size_t rl_len = requestedRespLevels[respFnCount].length(),
+           pl_len = requestedProbLevels[respFnCount].length(),
+           bl_len = requestedRelLevels[respFnCount].length(),
+           gl_len = requestedGenRelLevels[respFnCount].length(),
+           index, num_levels = rl_len + pl_len + bl_len + gl_len;
+
+    // Initialize (or warm-start for repeated reliability analyses) initialPtU,
+    // mostProbPointX/U, computedRespLevel, fnGradX/U, and fnHessX/U.
+    curvatureDataAvailable = false; // no data (yet) for this response function
+    if (num_levels)
+      initialize_level_data();
+
+    // Loop over response/probability/reliability levels
+    for (levelCount=0; levelCount<num_levels; levelCount++) {
+
+      // The rl_len response levels are performed first using the RIA
+      // formulation, followed by the pl_len probability levels and the
+      // bl_len reliability levels using the PMA formulation.
+      bool ria_flag = (levelCount < rl_len),
+	pma2_flag = ( integrationOrder == 2 && ( levelCount < rl_len + pl_len ||
+		      levelCount >= rl_len + pl_len + bl_len ) );
+      if (ria_flag) {
+        requestedTargetLevel = requestedRespLevels[respFnCount][levelCount];
+	Cout << "\n>>>>> Reliability Index Approach (RIA) for response level "
+	     << levelCount+1 << " = " << requestedTargetLevel << '\n';
+      }
+      else if (levelCount < rl_len + pl_len) {
+	index  = levelCount - rl_len;
+	Real p = requestedProbLevels[respFnCount][index];
+	Cout << "\n>>>>> Performance Measure Approach (PMA) for probability "
+	     << "level " << index + 1 << " = " << p << '\n';
+	// gen beta target for 2nd-order PMA; beta target for 1st-order PMA:
+	requestedTargetLevel = reliability(p);
+
+	// CDF probability < 0.5  -->  CDF beta > 0  -->  minimize g
+	// CDF probability > 0.5  -->  CDF beta < 0  -->  maximize g
+	// CDF probability = 0.5  -->  CDF beta = 0  -->  compute g
+	// Note: "compute g" means that min/max is irrelevant since there is
+	// a single G(u) value when the radius beta collapses to the origin
+	Real p_cdf   = (cdfFlag) ? p : 1. - p;
+	pmaMaximizeG = (p_cdf > 0.5); // updated in update_pma_maximize()
+      }
+      else if (levelCount < rl_len + pl_len + bl_len) {
+	index = levelCount - rl_len - pl_len;
+	requestedTargetLevel = requestedRelLevels[respFnCount][index];
+	Cout << "\n>>>>> Performance Measure Approach (PMA) for reliability "
+	     << "level " << index + 1 << " = " << requestedTargetLevel << '\n';
+	Real beta_cdf = (cdfFlag) ?
+	  requestedTargetLevel : -requestedTargetLevel;
+	pmaMaximizeG = (beta_cdf < 0.);
+      }
+      else {
+	index = levelCount - rl_len - pl_len - bl_len;
+	requestedTargetLevel = requestedGenRelLevels[respFnCount][index];
+	Cout << "\n>>>>> Performance Measure Approach (PMA) for generalized "
+	     << "reliability level " << index + 1 << " = "
+	     << requestedTargetLevel << '\n';
+	Real gen_beta_cdf = (cdfFlag) ?
+	  requestedTargetLevel : -requestedTargetLevel;
+	pmaMaximizeG = (gen_beta_cdf < 0.); // updated in update_pma_maximize()
+      }
+
+      // Assign cold/warm-start values for initialPtU, mostProbPointX/U,
+      // computedRespLevel, fnGradX/U, and fnHessX/U.
+      if (levelCount)
+	initialize_mpp_search_data();
+
+#ifdef DERIV_DEBUG
+      // numerical verification of analytic Jacobian/Hessian routines
+      if (mppSearchType == NO_APPROX && levelCount == 0)
+        mostProbPointU = ranVarMeansU;//mostProbPointX = ranVarMeansX;
+      //natafTransform.verify_trans_jacobian_hessian(mostProbPointU);
+      //natafTransform.verify_trans_jacobian_hessian(mostProbPointX);
+      natafTransform.verify_design_jacobian(mostProbPointU);
+#endif // DERIV_DEBUG
+
+      // For AMV+/TANA approximations, iterate until current expansion point
+      // converges to the MPP.
+      approxIters = 0;
+      approxConverged = false;
+      while (!approxConverged) {
+
+	Sizet2DArray vars_map, primary_resp_map, secondary_resp_map;
+	BoolDequeArray nonlinear_resp_map(2);
+	RecastModel* mpp_model_rep = (RecastModel*)mppModel.model_rep();
+	if (ria_flag) { // RIA: g is in constraint
+	  primary_resp_map.resize(1);   // one objective, no contributors
+	  secondary_resp_map.resize(1); // one constraint, one contributor
+	  secondary_resp_map[0].resize(1);
+	  secondary_resp_map[0][0] = respFnCount;
+	  nonlinear_resp_map[1] = BoolDeque(1, false);
+	  mpp_model_rep->initialize(vars_map, false, NULL, NULL,
+	    primary_resp_map, secondary_resp_map, nonlinear_resp_map,
+	    RIA_objective_eval, RIA_constraint_eval);
+	}
+	else { // PMA: g is in objective
+	  primary_resp_map.resize(1);   // one objective, one contributor
+	  primary_resp_map[0].resize(1);
+	  primary_resp_map[0][0] = respFnCount;
+	  secondary_resp_map.resize(1); // one constraint, no contributors
+	  nonlinear_resp_map[0] = BoolDeque(1, false);
+	  // If 2nd-order PMA with p-level or generalized beta-level, use
+	  // PMA2_set_mapping() & PMA2_constraint_eval().  For approx-based
+	  // 2nd-order PMA, we utilize curvature of the surrogate (if any)
+	  // to update beta*
+	  if (pma2_flag)
+	    mpp_model_rep->initialize(vars_map, false, NULL, PMA2_set_mapping,
+	      primary_resp_map, secondary_resp_map, nonlinear_resp_map,
+	      PMA_objective_eval, PMA2_constraint_eval);
+	  else
+	    mpp_model_rep->initialize(vars_map, false, NULL, NULL,
+	      primary_resp_map, secondary_resp_map, nonlinear_resp_map,
+	      PMA_objective_eval, PMA_constraint_eval);
+	}
+	mppModel.continuous_variables(initialPtU);
+
+        // Execute MPP search and retrieve u-space results
+        Cout << "\n>>>>> Initiating search for most probable point (MPP)\n";
+	ParLevLIter pl_iter
+	  = methodPCIter->mi_parallel_level_iterator(miPLIndex);
+	mppOptimizer.run(pl_iter);
+        const Variables& vars_star = mppOptimizer.variables_results();
+        const Response&  resp_star = mppOptimizer.response_results();
+	const RealVector& fns_star = resp_star.function_values();
+        Cout << "\nResults of MPP optimization:\nInitial point (u-space) =\n"
+             << initialPtU << "Final point (u-space)   =\n";
+	write_data(Cout, vars_star.continuous_variables());
+	if (ria_flag)
+	  Cout << "RIA optimum             =\n                     "
+	       << std::setw(write_precision+7) << fns_star[0] << " [u'u]\n"
+	       << "                     " << std::setw(write_precision+7)
+	       << fns_star[1] << " [G(u) - z]\n";
+	else {
+	  Cout << "PMA optimum             =\n                     "
+	       << std::setw(write_precision+7) << fns_star[0] << " [";
+	  if (pmaMaximizeG) Cout << '-';
+	  Cout << "G(u)]\n                     " << std::setw(write_precision+7)
+	       << fns_star[1];
+	  if (pma2_flag) Cout << " [B* - bar-B*]\n";
+	  else           Cout << " [u'u - B^2]\n";
+	}
+
+	// Update MPP search data
+	update_mpp_search_data(vars_star, resp_star);
+
+      } // end AMV+ while loop
+
+      // Update response/probability/reliability level data
+      update_level_data();
+
+      statCount++;
+    } // end loop over levels
+  } // end loop over response fns
+
+  // Update warm-start data
+  if (warmStartFlag && subIteratorFlag) // view->copy
+    copy_data(iteratedModel.inactive_continuous_variables(), prevICVars);
+
+  // This function manages either component or system reliability metrics
+  // via post-processing of computed{Resp,Prob,Rel,GenRel}Levels
+  update_final_statistics();
+
+  // restore in case of recursion
+  nondLocRelInstance = prev_instance;
+}
+
+
+/** An initial first- or second-order Taylor-series approximation is
+    required for MV/AMV/AMV+/TANA or for the case where momentStats
+    (from MV) are required within finalStatistics for subIterator
+    usage of NonDLocalReliability. */
+void NonDLocalReliability::initial_taylor_series()
+{
+  bool init_ts_flag = (mppSearchType < NO_APPROX); // updated below
+  const String& hess_type = iteratedModel.hessian_type();
+  size_t i, j, k;
+  ShortArray asrv(numFunctions, 0);
+  short mode = 3;
+  if (taylorOrder == 2 && hess_type != "quasi") // no data yet in quasiHess
+    mode |= 4;
+
+  const ShortArray& final_asv = finalStatistics.active_set_request_vector();
+  switch (mppSearchType) {
+  case MV:
+    asrv.assign(numFunctions, mode);
+    break;
+  case AMV_X:      case AMV_U:
+  case AMV_PLUS_X: case AMV_PLUS_U:
+  case TANA_X:     case TANA_U:
+    for (i=0; i<numFunctions; ++i)
+      if (!requestedRespLevels[i].empty() || !requestedProbLevels[i].empty() ||
+	  !requestedRelLevels[i].empty()  || !requestedGenRelLevels[i].empty() )
+	asrv[i] = mode;
+    // no break: fall through
+  case NO_APPROX:
+    if (subIteratorFlag) {
+      // check final_asv for active mean and std deviation stats
+      size_t cntr = 0;
+      for (i=0; i<numFunctions; i++) {
+	for (j=0; j<2; j++) {
+	  if (final_asv[cntr++]) { // mean, std deviation
+	    asrv[i] = mode;
+	    init_ts_flag = true;
+	  }
+	}
+	cntr += requestedRespLevels[i].length() +
+	  requestedProbLevels[i].length() + requestedRelLevels[i].length() +
+	  requestedGenRelLevels[i].length();
+      }
+    }
+    break;
+  }
+
+  momentStats.shape(2, numFunctions); // init to 0
+  if (init_ts_flag) {
+    bool correlation_flag = natafTransform.x_correlation();
+    // Evaluate response values/gradients at the mean values of the uncertain
+    // vars for the (initial) Taylor series expansion in MV/AMV/AMV+.
+    Cout << "\n>>>>> Evaluating response at mean values\n";
+    if (mppSearchType && mppSearchType < NO_APPROX)
+      uSpaceModel.component_parallel_mode(TRUTH_MODEL);
+    iteratedModel.continuous_variables(natafTransform.x_means());
+    activeSet.request_vector(asrv);
+    iteratedModel.compute_response(activeSet);
+    const Response& curr_resp = iteratedModel.current_response();
+    fnValsMeanX       = curr_resp.function_values();
+    fnGradsMeanX      = curr_resp.function_gradients();
+    if (mode & 4)
+      fnHessiansMeanX = curr_resp.function_hessians();
+
+    // compute the covariance matrix from the correlation matrix
+    RealSymMatrix covariance;
+    const Pecos::RealVector& x_std_devs = natafTransform.x_std_deviations();
+    if (correlation_flag) {
+      covariance.shapeUninitialized(numUncertainVars);
+      const Pecos::RealSymMatrix& x_corr_mat
+	= natafTransform.x_correlation_matrix();
+      for (i=0; i<numUncertainVars; i++) {
+	for (j=0; j<=i; j++) {
+	  covariance(i,j) = x_std_devs[i]*x_std_devs[j]*x_corr_mat(i,j);
+	  //if (i != j)
+	  //  covariance(j,i) = covariance(i,j);
+	}
+      }
+    }
+    else {
+      covariance.shape(numUncertainVars); // inits to 0
+      for (i=0; i<numUncertainVars; i++)
+	covariance(i,i) = std::pow(x_std_devs[i], 2);
+    }
+
+    // MVFOSM computes a first-order mean, which is just the response evaluated
+    // at the input variable means.  If Hessian data is available, compute a
+    // second-order mean including the effect of input variable correlations.
+    // MVFOSM computes a first-order variance including the effect of input
+    // variable correlations.  Second-order variance requires skewness/kurtosis
+    // of the inputs and is not practical.  NOTE: if fnGradsMeanX is zero, then
+    // std_dev will be zero --> bad for MV CDF estimates.
+    bool t2nq = (taylorOrder == 2 && hess_type != "quasi"); // 2nd-order mean
+    for (i=0; i<numFunctions; ++i) {
+      if (asrv[i]) {
+	Real& mean = momentStats(0,i); Real& std_dev = momentStats(1,i);
+	mean = fnValsMeanX[i]; // first-order mean
+	Real v1 = 0., v2 = 0.;
+	for (j=0; j<numUncertainVars; ++j) {
+	  Real fn_grad_ji = fnGradsMeanX(j,i);
+	  if (correlation_flag)
+	    for (k=0; k<numUncertainVars; ++k) {
+	      Real cov_jk = covariance(j,k);
+	      if (t2nq) v1 += cov_jk * fnHessiansMeanX[i](j,k);
+	      v2 += cov_jk * fn_grad_ji * fnGradsMeanX(k,i);
+	    }
+	  else {
+	    Real cov_jj = covariance(j,j);
+	    if (t2nq) v1 += cov_jj * fnHessiansMeanX[i](j,j);
+	    v2 += cov_jj * std::pow(fn_grad_ji, 2);
+	  }
+	}
+	if (t2nq) mean += v1/2.;
+	std_dev = std::sqrt(v2);
+      }
+    }
+
+    // Teuchos/BLAS-based approach.  As a matrix triple-product, this has some
+    // unneeded FLOPs.  A vector-matrix triple product would be preferable, but
+    // requires vector extractions from fnGradsMeanX.
+    //RealSymMatrix variance(numFunctions, false);
+    //Teuchos::symMatTripleProduct(Teuchos::NO_TRANS, 1., covariance,
+    //                             fnGradsMeanX, variance);
+    //for (i=0; i<numFunctions; i++)
+    //  momentStats(1,i) = sqrt(variance(i,i));
+    //Cout << "\nvariance = " << variance << "\nmomentStats = " << momentStats;
+  }
+}
+
+
+/** Initialize class-scope arrays and perform other start-up
+    activities, such as evaluating median limit state responses. */
+void NonDLocalReliability::initialize_class_data()
+{
+  // Initialize class-scope arrays used to warm-start multiple reliability
+  // analyses within a strategy such as bi-level/sequential RBDO.  Cannot be
+  // performed in constructor due to late availability of subIteratorFlag.
+  if (warmStartFlag && subIteratorFlag && numRelAnalyses == 0) {
+    size_t num_final_grad_vars
+      = finalStatistics.active_set_derivative_vector().size();
+    prevMPPULev0.resize(numFunctions);
+    prevCumASVLev0.assign(numFunctions, 0);
+    prevFnGradDLev0.shape(num_final_grad_vars, numFunctions);
+    prevFnGradULev0.shape(numUncertainVars, numFunctions);
+  }
+
+  // define ranVarMeansU for use in the transformed AMV option
+  //if (mppSearchType == AMV_U)
+  natafTransform.trans_X_to_U(natafTransform.x_means(), ranVarMeansU);
+  // must follow transform_correlations()
+
+  /*
+  // Determine median limit state values for AMV/AMV+/FORM/SORM by evaluating
+  // response fns at u = 0 (used for determining signs of reliability indices).
+  Cout << "\n>>>>> Evaluating response at median values\n";
+  if (mppSearchType && mppSearchType < NO_APPROX)
+    uSpaceModel.component_parallel_mode(TRUTH_MODEL);
+  RealVector ep_median_u(numUncertainVars), // inits vals to 0
+             ep_median_x(numUncertainVars, false);
+  natafTransform.trans_U_to_X(ep_median_u, ep_median_x);
+  iteratedModel.continuous_variables(ep_median_x);
+  activeSet.request_values(0); // initialize
+  for (size_t i=0; i<numFunctions; i++)
+    if (!requestedRespLevels[i].empty() || !requestedProbLevels[i].empty() ||
+	!requestedRelLevels[i].empty()  || !requestedGenRelLevels[i].empty())
+      activeSet.request_value(1, i); // only fn vals needed at median unc vars
+  iteratedModel.compute_response(activeSet);
+  medianFnVals = iteratedModel.current_response().function_values();
+  */
+
+  // now that vars/labels/bounds/targets have flowed down at run-time from any
+  // higher level recursions, propagate them up the instantiate-on-the-fly
+  // Model recursion so that they are correct when they propagate back down.
+  mppModel.update_from_subordinate_model(); // recurse_flag = true
+
+  // set up the x-space data within the importance sampler
+  if (integrationRefinement) { // IS/AIS/MMAIS
+    // rep needed for access to functions not mapped to Iterator level
+    NonDAdaptImpSampling* importance_sampler_rep
+      = (NonDAdaptImpSampling*)importanceSampler.iterator_rep();
+    importance_sampler_rep->initialize_random_variables(natafTransform);
+  }
+}
+
+
+/** For a particular response function prior to the first z/p/beta level,
+    initialize/warm-start optimizer initial guess (initialPtU),
+    expansion point (mostProbPointX/U), and associated response
+    data (computedRespLevel, fnGradX/U, and fnHessX/U). */
+void NonDLocalReliability::initialize_level_data()
+{
+  // All reliability methods need initialization of initialPtU; AMV/AMV+/TANA
+  // methods additionally need initialization of fnGradX/U; and AMV+/TANA
+  // methods additionally need initialization of mostProbPointX/U and
+  // computedRespLevel.
+
+  // If warm-starting across multiple NonDLocalReliability invocations (e.g.,
+  // for modified design parameters in RBDO), warm-start using the level 0 final
+  // results for the corresponding response fn.  For all subsequent levels,
+  // the warm-start procedure is self-contained (i.e., no data from the
+  // previous NonDLocalReliability invocation is used).
+
+  // For AMV+ across multiple NonDLocalReliability invocations, the previous
+  // level 0 converged MPP provides the basis for the initial expansion point.
+  // If inactive variable design sensitivities are available, a projection
+  // from the previous MPP is used.  In either case, re-evaluation of response
+  // data is required to capture the effect of inactive variable changes
+  // (design variables in RBDO).  Since the mean expansion at the new d
+  // has already been computed, one could also use this since it may predict
+  // an MPP estimate (after one opt cycle, prior to the expense of the second
+  // expansion evaluation) as good as the converged/projected MPP at the
+  // old d.  However, the former approach has been observed to be preferable
+  // in practice (even without projection).
+
+  if (warmStartFlag && subIteratorFlag && numRelAnalyses) {
+    // level 0 of each response fn in subsequent UQ analysis: initial
+    // optimizer guess and initial expansion point are the converged
+    // MPP from the previous UQ analysis, for which the computedRespLevel
+    // and fnGradX/U must be re-evaluated due to design variable changes.
+
+    // simplest approach
+    initialPtU = prevMPPULev0[respFnCount]; // AMV/AMV+/FORM
+
+    // If inactive var sensitivities are available, then apply a correction
+    // to initialPtU using a design sensitivity projection (Burton & Hajela).
+    // Note 1: only valid for RIA.
+    // Note 2: when the top level RBDO optimizer is performing a value-based
+    // line search, it is possible for prevFnGradDLev0 to be older than
+    // prevICVars/prevMPPULev0/prevFnGradULev0.  In testing, this appears to
+    // be OK and preferable to bypassing the projection when prevFnGradDLev0
+    // is out of date (which is why the previous ASV test is cumulative: if
+    // prevFnGradDLev0 has been populated, use it whether or not it was from
+    // the last analysis).
+    bool inactive_grads = (prevCumASVLev0[respFnCount] & 2)    ? true : false;
+    bool lev0_ria = (requestedRespLevels[respFnCount].empty()) ? false : true;
+    if (inactive_grads && lev0_ria) {
+      RealVector fn_grad_d = Teuchos::getCol(Teuchos::View, prevFnGradDLev0,
+                                             respFnCount);
+      RealVector fn_grad_u = Teuchos::getCol(Teuchos::View, prevFnGradULev0,
+                                             respFnCount);
+      const RealVector& d_k_plus_1
+	= iteratedModel.inactive_continuous_variables(); // view
+      Real grad_d_delta_d = 0., norm_grad_u_sq = 0.;
+      size_t i, num_icv = d_k_plus_1.length();
+      for (i=0; i<num_icv; i++)
+	grad_d_delta_d += fn_grad_d[i]*( d_k_plus_1[i] - prevICVars[i] );
+      for (i=0; i<numUncertainVars; i++)
+	norm_grad_u_sq += std::pow(fn_grad_u[i], 2);
+      Real factor = grad_d_delta_d / norm_grad_u_sq;
+      for (i=0; i<numUncertainVars; i++)
+	initialPtU[i] -= factor * fn_grad_u[i];
+    }
+
+    if (mppSearchType == AMV_X || mppSearchType == AMV_U) {
+      // Reevaluation for new des vars already performed at uncertain var means
+      // in initial_taylor_series()
+      assign_mean_data();
+    }
+    else if (mppSearchType == AMV_PLUS_X || mppSearchType == AMV_PLUS_U ||
+	     mppSearchType == TANA_X     || mppSearchType == TANA_U) {
+      mostProbPointU = initialPtU;
+      natafTransform.trans_U_to_X(mostProbPointU, mostProbPointX);
+      if (inactive_grads)
+	Cout << "\n>>>>> Evaluating new response at projected MPP\n";
+      else
+	Cout << "\n>>>>> Evaluating new response at previous MPP\n";
+      uSpaceModel.component_parallel_mode(TRUTH_MODEL);
+      // set active/uncertain vars augmenting inactive design vars
+      iteratedModel.continuous_variables(mostProbPointX);
+      short mode = (taylorOrder == 2) ? 7 : 3;
+      activeSet.request_values(0); activeSet.request_value(mode, respFnCount);
+
+      iteratedModel.compute_response(activeSet);
+      const Response& curr_resp = iteratedModel.current_response();
+      computedRespLevel = curr_resp.function_value(respFnCount);
+      fnGradX = curr_resp.function_gradient_copy(respFnCount);
+
+      SizetMultiArrayConstView cv_ids = iteratedModel.continuous_variable_ids();
+      SizetArray x_dvv; copy_data(cv_ids, x_dvv);
+      natafTransform.trans_grad_X_to_U(fnGradX, fnGradU, mostProbPointX,
+				       x_dvv, cv_ids);
+      if (mode & 4) {
+	fnHessX = curr_resp.function_hessian(respFnCount);
+	natafTransform.trans_hess_X_to_U(fnHessX, fnHessU, mostProbPointX,
+					 fnGradX, x_dvv, cv_ids);
+	curvatureDataAvailable = true; kappaUpdated = false;
+      }
+    }
+  }
+  else { // level 0 of each response fn in first or only UQ analysis
+
+    // initial fnGradX/U for AMV/AMV+ = grads at mean x values, initial
+    // expansion point for AMV+ = mean x values.
+    if (mppSearchType < NO_APPROX) { // AMV/AMV+/TANA
+      // update mostProbPointX/U, computedRespLevel, fnGradX/U, fnHessX/U
+      assign_mean_data();
+#ifdef MPP_CONVERGE_RATE
+      if (mppSearchType >= AMV_PLUS_X)
+	Cout << "u'u = "  << mostProbPointU.dot(mostProbPointU)
+	     << " G(u) = " << computedRespLevel << '\n';
+#endif // MPP_CONVERGE_RATE
+    }
+
+    // initial optimizer guess in u-space (initialPtU)
+    initialPtU = initialPtUSpec; // initialPtUSpec set in ctor
+
+    /*
+    // fall back if projection is unavailable (or numerics don't work out).
+    initialPtU = (ria_flag) ? initialPtUSpec :
+      std::fabs(requestedCDFRelLevel)/std::sqrt((Real)numUncertainVars);
+
+    // if fnValsMeanX/fnGradU are available, then warm start initialPtU using
+    // a projection from the means.
+    if (warmStartFlag && mv_flag) {
+      Real alpha, norm_grad_u_sq = fnGradU.dot(fnGradU);
+      if (ria_flag) {
+	// use same projection idea as for a z level change,
+	// but project from means
+	if ( norm_grad_u_sq > 1.e-10 ) {
+	  alpha = (requestedRespLevel - fnValsMeanX[respFnCount])
+	        / norm_grad_u_sq;
+	  for (i=0; i<numUncertainVars; i++)
+	    initialPtU[i] = ranVarMeansU[i] + alpha*fnGradU[i];
+	}
+      }
+      else { // pma
+	// the simple projection for a beta level change does not work here
+	// since beta at means will be near-zero (zero if x-space is normally
+	// distributed).  Therefore, solve for the alpha value in
+	// u = u_mean + alpha*dg/du which yields ||u|| = beta.  This requires
+	// solving the quadratic expression a alpha^2 + b alpha + c = 0 with
+	// a = dg/du^T dg/du, b = 2 dg/du^T u_mean, and
+	// c = u_mean^T u_mean - beta^2
+	Real b = 2. * ranVarMeansU.dot(fnGradU),
+	     c = ranVarMeansU.dot(ranVarMeansU) - pow(requestedCDFRelLevel, 2);
+	Real b2m4ac = b*b - 4.*norm_grad_u_sq*c;
+	if (b2m4ac >= 0. && norm_grad_u_sq > 1.e-10) {
+	  Real alpha1 = (-b + std::sqrt(b2m4ac))/2./norm_grad_u_sq,
+	       alpha2 = (-b - std::sqrt(b2m4ac))/2./norm_grad_u_sq,
+	       g_est1 = fnValsMeanX[respFnCount] + alpha1*norm_grad_u_sq;
+	  // Select the correct root based on sign convention involving beta
+	  // and relationship of projected G to G(0):
+	  if (requestedCDFRelLevel >= 0.)
+	    // if beta_cdf >= 0, then projected G should be <= G(0)
+	    alpha = (g_est1 <= medianFnVals[respFnCount]) ? alpha1 : alpha2;
+	  else
+	    // if beta_cdf <  0, then projected G should be >  G(0)
+	    alpha = (g_est1 >  medianFnVals[respFnCount]) ? alpha1 : alpha2;
+	  for (i=0; i<numUncertainVars; i++)
+	    initialPtU[i] = ranVarMeansU[i] + alpha*fnGradU[i];
+	}
+      }
+    }
+    */
+  }
+
+  // Create the initial Taylor series approximation used by AMV/AMV+/TANA
+  if (mppSearchType < NO_APPROX) {
+    // restrict the approximation index set
+    IntSet surr_fn_indices;
+    surr_fn_indices.insert(respFnCount);
+    uSpaceModel.surrogate_function_indices(surr_fn_indices);
+    // construct the approximation
+    update_limit_state_surrogate();
+  }
+}
+
+
+/** For a particular response function at a particular z/p/beta level,
+    warm-start or reset the optimizer initial guess (initialPtU),
+    expansion point (mostProbPointX/U), and associated response
+    data (computedRespLevel, fnGradX/U, and fnHessX/U). */
+void NonDLocalReliability::initialize_mpp_search_data()
+{
+  if (warmStartFlag) {
+    // For subsequent levels (including an RIA to PMA switch), warm start by
+    // using the MPP from the previous level as the initial expansion
+    // point.  The initial guess for the next MPP optimization is warm
+    // started either by a simple copy of the MPP in the case of unconverged
+    // AMV+ iterations (see AMV+ convergence assessment below) or, in the
+    // case of an advance to the next level, by projecting from the current
+    // MPP out to the new beta radius or response level.
+    // NOTE: premature opt. termination can occur if the RIA/PMA 1st-order
+    // optimality conditions (u + lamba*grad_g = 0 or grad_g + lambda*u = 0)
+    // remain satisfied for the new level, even though the new equality
+    // constraint will be violated.  The projection addresses this concern.
+
+    // No action is required for warm start of mostProbPointX/U, fnGradX/U,
+    // and computedRespLevel (not indexed by level)
+
+    // Warm start initialPtU for the next level using a projection.
+    size_t rl_len = requestedRespLevels[respFnCount].length();
+    if (levelCount < rl_len) {
+      // For RIA case, project along fnGradU to next g level using
+      // linear Taylor series:  g2 = g1 + dg/du^T (u2 - u1) where
+      // u2 - u1 = alpha*dg/du gives alpha = (g2 - g1)/(dg/du^T dg/du).
+      // NOTE 1: the requested and computed response levels will differ in
+      // the AMV case.  While the previous computed response level could be
+      // used in the alpha calculation, the ratio of requested levels should
+      // be a more accurate predictor of the next linearized AMV MPP.
+      // NOTE 2: this projection could bypass the need for fnGradU with
+      // knowledge of the Lagrange multipliers at the previous MPP
+      // (u + lamba*grad_g = 0 or grad_g + lambda*u = 0).
+      Real norm_grad_u_sq = fnGradU.dot(fnGradU);
+      if ( norm_grad_u_sq > 1.e-10 ) { // also handles NPSOL numerical case
+	Real alpha = (requestedTargetLevel -
+          requestedRespLevels[respFnCount][levelCount-1])/norm_grad_u_sq;
+	for (size_t i=0; i<numUncertainVars; i++)
+	  initialPtU[i] = mostProbPointU[i] + alpha * fnGradU[i];
+      }
+      else
+	initialPtU = initialPtUSpec;//mostProbPointU: premature conv w/ some opt
+    }
+    else {
+      // For PMA case, scale mostProbPointU so that its magnitude equals
+      // the next beta_target.
+      // NOTE 1: use of computed levels instead of requested levels handles
+      // an RIA/PMA switch (the observed reliability from the RIA soln is
+      // scaled to the requested reliability of the next PMA level).
+      // NOTE 2: requested and computed reliability levels should agree very
+      // closely in all cases since it is the g term that is linearized, not the
+      // u'u term (which defines beta).  However, if the optimizer fails to
+      // satisfy the PMA constraint, then using the computed level is preferred.
+      //Real prev_pl = (levelCount == rl_len)
+      //  ? computedProbLevels[respFnCount][levelCount-1]
+      //  : requestedProbLevels[respFnCount][levelCount-rl_len-1];
+      size_t pl_len = requestedProbLevels[respFnCount].length(),
+	     bl_len = requestedRelLevels[respFnCount].length();
+      Real prev_bl = ( integrationOrder == 2 &&
+		       ( levelCount <  rl_len + pl_len ||
+			 levelCount >= rl_len + pl_len + bl_len ) ) ?
+	computedGenRelLevels[respFnCount][levelCount-1] :
+	computedRelLevels[respFnCount][levelCount-1];
+      // Note: scaling is applied to mppU, so we want best est of new beta.
+      // Don't allow excessive init pt scaling if secant Hessian updating.
+      Real high_tol = 1.e+3,
+	low_tol = ( ( taylorOrder == 2 || integrationOrder == 2 ) &&
+		    iteratedModel.hessian_type() == "quasi" ) ? 1.e-3 : 1.e-10;
+      if ( std::abs(prev_bl) > low_tol && std::abs(prev_bl) < high_tol &&
+	   std::abs(requestedTargetLevel) > low_tol &&
+	   std::abs(requestedTargetLevel) < high_tol ) {
+	// CDF or CCDF does not matter for scale_factor so long as it is
+	// consistent (CDF/CDF or CCDF/CCDF).
+	Real scale_factor = requestedTargetLevel / prev_bl;
+#ifdef DEBUG
+	Cout << "PMA warm start: previous = " << prev_bl
+	     << " current = " << requestedTargetLevel
+	     << " scale_factor = " << scale_factor << std::endl;
+#endif // DEBUG
+	for (size_t i=0; i<numUncertainVars; i++)
+	  initialPtU[i] = mostProbPointU[i] * scale_factor;
+      }
+      else
+	initialPtU = initialPtUSpec;//mostProbPointU: premature conv w/ some opt
+    }
+  }
+  else { // cold start: reset to mean inputs/outputs
+    // initial fnGradX/U for AMV/AMV+ = grads at mean x values, initial
+    // expansion point for AMV+ = mean x values.
+    if (mppSearchType < NO_APPROX) // AMV/AMV+/TANA
+      assign_mean_data();
+    // initial optimizer guess in u-space (initialPtU)
+    initialPtU = initialPtUSpec; // initialPtUSpec set in ctor
+  }
+}
+
+
+/** Includes case-specific logic for updating MPP search data for the
+    AMV/AMV+/TANA/NO_APPROX methods. */
+void NonDLocalReliability::
+update_mpp_search_data(const Variables& vars_star, const Response& resp_star)
+{
+  size_t rl_len = requestedRespLevels[respFnCount].length(),
+         pl_len = requestedProbLevels[respFnCount].length(),
+         bl_len = requestedRelLevels[respFnCount].length();
+  bool ria_flag = (levelCount < rl_len);
+  const RealVector&    mpp_u = vars_star.continuous_variables(); // view
+  const RealVector& fns_star = resp_star.function_values();
+
+  // Update MPP arrays from optimization results
+  Real conv_metric;
+  switch (mppSearchType) {
+  case AMV_PLUS_X: case AMV_PLUS_U: case TANA_X: case TANA_U:
+    RealVector del_u(numUncertainVars, false);
+    for (size_t i=0; i<numUncertainVars; i++)
+      del_u[i] = mpp_u[i] - mostProbPointU[i];
+    conv_metric = del_u.normFrobenius();
+    break;
+  }
+  copy_data(mpp_u, mostProbPointU); // view -> copy
+  natafTransform.trans_U_to_X(mostProbPointU, mostProbPointX);
+
+  // Set computedRespLevel to the current g(x) value by either performing
+  // a validation function evaluation (AMV/AMV+) or retrieving data from
+  // resp_star (FORM).  Also update approximations and convergence tols.
+  SizetMultiArrayConstView cv_ids = iteratedModel.continuous_variable_ids();
+  SizetArray x_dvv; copy_data(cv_ids, x_dvv);
+  switch (mppSearchType) {
+  case AMV_X: case AMV_U: {
+    approxConverged = true; // break out of while loop
+    uSpaceModel.component_parallel_mode(TRUTH_MODEL);
+    activeSet.request_values(0); activeSet.request_value(1, respFnCount);
+    iteratedModel.continuous_variables(mostProbPointX);
+    iteratedModel.compute_response(activeSet);
+    computedRespLevel
+      = iteratedModel.current_response().function_value(respFnCount);
+    break;
+  }
+  case AMV_PLUS_X: case AMV_PLUS_U: case TANA_X: case TANA_U: {
+    // Assess AMV+/TANA iteration convergence.  ||del_u|| is not a perfect
+    // metric since cycling between MPP estimates can occur.  Therefore,
+    // a maximum number of iterations is also enforced.
+    //conv_metric = std::fabs(fn_vals[respFnCount] - requestedRespLevel);
+    ++approxIters;
+    if (conv_metric < convergenceTol)
+      approxConverged = true;
+    else if (approxIters >= maxIterations) {
+      Cerr << "\nWarning: maximum number of limit state approximation cycles "
+	   << "exceeded.\n";
+      warningBits |= 1; // first warning in output summary
+      approxConverged = true;
+    }
+    // Update response data for local/multipoint MPP approximation
+    short mode = 1;
+    if (approxConverged) {
+      Cout << "\n>>>>> Approximate MPP iterations converged.  "
+	   << "Evaluating final response.\n";
+      // fnGradX/U needed for warm starting by projection, final_stat_grad,
+      // and/or 2nd-order integration.
+      const ShortArray& final_asv = finalStatistics.active_set_request_vector();
+      if ( warmStartFlag || ( final_asv[statCount] & 2 ) )
+	mode |= 2;
+      if (integrationOrder == 2) {
+	mode |= 4;
+	if (numUncertainVars != numNormalVars)
+	  mode |= 2; // fnGradX needed to transform fnHessX to fnHessU
+      }
+    }
+    else { // not converged
+      Cout << "\n>>>>> Updating approximation for MPP iteration "
+	   << approxIters+1 << "\n";
+      mode |= 2;            // update AMV+/TANA approximation
+      if (taylorOrder == 2) // update AMV^2+ approximation
+	mode |= 4;
+      if (warmStartFlag) // warm start initialPtU for next AMV+ iteration
+	initialPtU = mostProbPointU;
+    }
+    // evaluate new expansion point
+    uSpaceModel.component_parallel_mode(TRUTH_MODEL);
+    activeSet.request_values(0);
+    activeSet.request_value(mode, respFnCount);
+    iteratedModel.continuous_variables(mostProbPointX);
+    iteratedModel.compute_response(activeSet);
+    const Response& curr_resp = iteratedModel.current_response();
+    computedRespLevel = curr_resp.function_value(respFnCount);
+#ifdef MPP_CONVERGE_RATE
+    Cout << "u'u = "  << mostProbPointU.dot(mostProbPointU)
+	 << " G(u) = " << computedRespLevel << '\n';
+#endif // MPP_CONVERGE_RATE
+    if (mode & 2) {
+      fnGradX = curr_resp.function_gradient_copy(respFnCount);
+      natafTransform.trans_grad_X_to_U(fnGradX, fnGradU, mostProbPointX,
+				       x_dvv, cv_ids);
+    }
+    if (mode & 4) {
+      fnHessX = curr_resp.function_hessian(respFnCount);
+      natafTransform.trans_hess_X_to_U(fnHessX, fnHessU, mostProbPointX,
+				       fnGradX, x_dvv, cv_ids);
+      curvatureDataAvailable = true; kappaUpdated = false;
+    }
+
+    // Update the limit state surrogate model
+    update_limit_state_surrogate();
+
+    // Update pmaMaximizeG if 2nd-order PMA for specified p / beta* level
+    if ( !approxConverged && !ria_flag && integrationOrder == 2 )
+      update_pma_maximize(mostProbPointU, fnGradU, fnHessU);
+
+    break;
+  }
+  case NO_APPROX: { // FORM/SORM
+
+    // direct optimization converges to MPP: no new approximation to compute
+    approxConverged = true; // break out of while loop
+    if (ria_flag) // RIA computed response = eq_con_star + response target
+      computedRespLevel = fns_star[1] + requestedTargetLevel;
+    else          // PMA computed response = +/- obj_fn_star
+      computedRespLevel = (pmaMaximizeG) ? -fns_star[0] : fns_star[0];
+
+    // fnGradX/U needed for warm starting by projection, final_stat_grad, and/or
+    // 2nd-order integration (for nonlinear transformations), and should be
+    // retrievable from previous evals.  If second-order integration for RIA,
+    // fnHessX/U also needed, but not retrievable.  If second-order PMA with
+    // specified p-level, Hessian should be retrievable since it was computed
+    // during the update of requestedCDFRelLevel from requestedCDFProbLevel.
+    // When data should be retrievable, we cannot in general assume that the
+    // last grad/Hessian eval corresponds to the converged MPP; therefore, we
+    // use a DB search.  If the DB search fails (e.g., the eval cache is
+    // deactivated), then we resort to reevaluation.
+    short mode = 0, found_mode = 0; // computedRespLevel already retrieved
+    const ShortArray& final_asv = finalStatistics.active_set_request_vector();
+    if ( warmStartFlag || ( final_asv[statCount] & 2 ) )
+      mode |= 2;
+    if ( integrationOrder == 2 ) {// apply 2nd-order integr in all RIA/PMA cases
+      mode |= 4;
+      if (numUncertainVars != numNormalVars)
+	mode |= 2; // fnGradX needed to transform fnHessX to fnHessU
+    }
+
+    // retrieve previously evaluated gradient information, if possible
+    if (mode & 2) { // avail in all RIA/PMA cases (exception: numerical grads)
+      // query data_pairs to retrieve the fn gradient at the MPP
+      Variables search_vars = iteratedModel.current_variables().copy();
+      search_vars.continuous_variables(mostProbPointX);
+      ActiveSet search_set = resp_star.active_set();
+      ShortArray search_asv(numFunctions, 0);
+      search_asv[respFnCount] = 2;
+      search_set.request_vector(search_asv);
+      PRPCacheHIter cache_it = lookup_by_val(data_pairs,
+	iteratedModel.interface_id(), search_vars, search_set);
+      if (cache_it != data_pairs.get<hashed>().end()) {
+	fnGradX = cache_it->response().function_gradient_copy(respFnCount);
+	found_mode |= 2;
+      }
+    }
+    // retrieve previously evaluated Hessian information, if possible
+    // > RIA and std PMA beta-level: Hessian not avail since not yet evaluated
+    // > PMA p-level and generalized beta-level: Hessian should be available
+    if ( ( mode & 4 ) && !ria_flag &&
+	 ( levelCount <  rl_len + pl_len ||
+	   levelCount >= rl_len + pl_len + bl_len ) ) {
+      // query data_pairs to retrieve the fn Hessian at the MPP
+      Variables search_vars = iteratedModel.current_variables().copy();
+      search_vars.continuous_variables(mostProbPointX);
+      ActiveSet search_set = resp_star.active_set();
+      ShortArray search_asv(numFunctions, 0);
+      search_asv[respFnCount] = 4;
+      search_set.request_vector(search_asv);
+      PRPCacheHIter cache_it = lookup_by_val(data_pairs,
+	iteratedModel.interface_id(), search_vars, search_set);
+      if (cache_it != data_pairs.get<hashed>().end()) {
+        fnHessX = cache_it->response().function_hessian(respFnCount);
+	found_mode |= 4;
+      }
+    }
+    // evaluate any remaining required data which could not be retrieved
+    short remaining_mode = mode - found_mode;
+    if (remaining_mode) {
+      Cout << "\n>>>>> Evaluating limit state derivatives at MPP\n";
+      iteratedModel.continuous_variables(mostProbPointX);
+      activeSet.request_values(0);
+      activeSet.request_value(remaining_mode, respFnCount);
+      iteratedModel.compute_response(activeSet);
+      const Response& curr_resp = iteratedModel.current_response();
+      if (remaining_mode & 2)
+	fnGradX = curr_resp.function_gradient_copy(respFnCount);
+      if (remaining_mode & 4)
+        fnHessX = curr_resp.function_hessian(respFnCount);
+    }
+    if (mode & 2)
+      natafTransform.trans_grad_X_to_U(fnGradX, fnGradU, mostProbPointX,
+				       x_dvv, cv_ids);
+    if (mode & 4) {
+      natafTransform.trans_hess_X_to_U(fnHessX, fnHessU, mostProbPointX,
+				       fnGradX, x_dvv, cv_ids);
+      curvatureDataAvailable = true; kappaUpdated = false;
+    }
+    break;
+  }
+  }
+
+  // set computedRelLevel using u'u from fns_star; must follow fnGradU update
+  if (ria_flag)
+    computedRelLevel = signed_norm(std::sqrt(fns_star[0]));
+  else if (integrationOrder == 2) { // second-order PMA
+    // no op: computed{Rel,GenRel}Level updated in PMA2_constraint_eval()
+  }
+  else { // first-order PMA
+    Real norm_u_sq = fns_star[1] + std::pow(requestedTargetLevel, 2);
+    computedRelLevel = signed_norm(std::sqrt(norm_u_sq));
+  }
+}
+
+
+/** Updates computedRespLevels/computedProbLevels/computedRelLevels,
+    finalStatistics, warm start, and graphics data. */
+void NonDLocalReliability::update_level_data()
+{
+  // local reliability data aren't output to tabular, so send directly
+  // to graphics window only
+  Graphics& dakota_graphics = parallelLib.output_manager().graphics();
+
+  bool ria_flag = (levelCount < requestedRespLevels[respFnCount].length());
+
+  // Update computed Resp/Prob/Rel/GenRel levels arrays.  finalStatistics
+  // is updated within update_final_statistics() for all resp fns & levels.
+  computedRespLevels[respFnCount][levelCount] = computedRespLevel;
+  computedRelLevels[respFnCount][levelCount]  = computedRelLevel;
+  Real computed_prob_level;
+  if (!ria_flag && integrationOrder == 2) {
+    computedGenRelLevels[respFnCount][levelCount] = computedGenRelLevel;
+    computedProbLevels[respFnCount][levelCount] = computed_prob_level =
+      probability(computedGenRelLevel);
+  }
+  else {
+    computedProbLevels[respFnCount][levelCount] = computed_prob_level =
+      probability(computedRelLevel, cdfFlag, mostProbPointU, fnGradU, fnHessU);
+    computedGenRelLevels[respFnCount][levelCount] = computedGenRelLevel =
+      reliability(computed_prob_level);
+  }
+
+  // Final statistic gradients are dz/ds, dbeta/ds, or dp/ds
+  const ShortArray& final_asv = finalStatistics.active_set_request_vector();
+  bool system_grad_contrib = false;
+  if (respLevelTargetReduce &&
+      levelCount < requestedRespLevels[respFnCount].length()) {
+    size_t sys_stat_count = 2*numFunctions + totalLevelRequests + levelCount;
+    if (final_asv[sys_stat_count] & 2)
+      system_grad_contrib = true;
+  }
+  if ( (final_asv[statCount] & 2) || system_grad_contrib ) {
+
+    // evaluate dg/ds at the MPP and store in final_stat_grad
+    RealVector final_stat_grad;
+    dg_ds_eval(mostProbPointX, fnGradX, final_stat_grad);
+
+    // for warm-starting next run
+    if (warmStartFlag && subIteratorFlag && levelCount == 0)
+      Teuchos::setCol(final_stat_grad, respFnCount, prevFnGradDLev0);
+
+    // RIA: sensitivity of beta/p/beta* w.r.t. inactive variables
+    //   dbeta/ds     = 1/norm_grad_u * dg/ds       (first-order)
+    //   dp/ds        = -phi(-beta) * dbeta/ds      (first-order)
+    //   dp_2/ds      = [Phi(-beta_corr)*sum - phi(-beta_corr)*prod] * dbeta/ds
+    //                                              (second-order)
+    //   dbeta*/ds    = -1/phi(-beta*) * dp_2/ds    (second-order)
+    // PMA: sensitivity of g function w.r.t. inactive variables
+    //   dz/ds        = dg/ds
+    if (ria_flag) {
+      // beta_cdf = -beta_ccdf, p_cdf = 1. - p_ccdf
+      // -->> dbeta_cdf/ds = -dbeta_ccdf/ds, dp_cdf/ds = -dp_ccdf/ds
+      Real norm_grad_u = fnGradU.normFrobenius();
+      // factor for first-order dbeta/ds:
+      Real factor = (cdfFlag) ? 1./norm_grad_u : -1./norm_grad_u;
+      if (integrationOrder == 2 && respLevelTarget != RELIABILITIES) {
+	factor *= dp2_dbeta_factor(computedRelLevel, cdfFlag);
+	// factor for second-order dbeta*/ds
+	if (respLevelTarget == GEN_RELIABILITIES)
+	  factor *= -1. / Pecos::phi(-computedGenRelLevel);
+      }
+      else if (respLevelTarget == PROBABILITIES) // factor for first-order dp/ds
+	factor *= -Pecos::phi(-computedRelLevel);
+
+      // apply factor:
+      size_t i, num_final_grad_vars
+	= finalStatistics.active_set_derivative_vector().size();
+      for (i=0; i<num_final_grad_vars; ++i)
+	final_stat_grad[i] *= factor;
+    }
+    finalStatistics.function_gradient(final_stat_grad, statCount);
+  }
+
+  // Update warm-start data and graphics
+  if (warmStartFlag && subIteratorFlag && levelCount == 0) {
+    // for warm-starting next run
+    prevMPPULev0[respFnCount] = mostProbPointU;
+    prevCumASVLev0[respFnCount] |= final_asv[statCount];
+    for (size_t i=0; i<numUncertainVars; i++)
+      prevFnGradULev0(i,respFnCount) = fnGradU[i];
+  }
+  if (!subIteratorFlag) {
+    dakota_graphics.add_datapoint(respFnCount, computedRespLevel,
+				  computed_prob_level);
+    for (size_t i=0; i<numUncertainVars; i++) {
+      dakota_graphics.add_datapoint(numFunctions+i, computedRespLevel,
+				    mostProbPointX[i]);
+      if (numFunctions > 1 && respFnCount < numFunctions-1 &&
+	  levelCount == requestedRespLevels[respFnCount].length() +
+	                requestedProbLevels[respFnCount].length() +
+	                requestedRelLevels[respFnCount].length() +
+	                requestedGenRelLevels[respFnCount].length() - 1)
+	dakota_graphics.new_dataset(numFunctions+i);
+    }
+  }
+}
+
+
+void NonDLocalReliability::update_limit_state_surrogate()
+{
+  bool x_space = (mppSearchType ==  AMV_X || mppSearchType == AMV_PLUS_X ||
+		  mppSearchType == TANA_X);
+
+  // construct local Variables object
+  Variables mpp_vars(iteratedModel.current_variables().shared_data());
+  if (x_space) mpp_vars.continuous_variables(mostProbPointX);
+  else         mpp_vars.continuous_variables(mostProbPointU);
+
+  // construct Response object
+  ShortArray asv(numFunctions, 0);
+  asv[respFnCount] = (taylorOrder == 2) ? 7 : 3;
+  ActiveSet set;//(numFunctions, numUncertainVars);
+  set.request_vector(asv);
+  set.derivative_vector(iteratedModel.continuous_variable_ids());
+  Response response(SIMULATION_RESPONSE, set);
+  response.function_value(computedRespLevel, respFnCount);
+  if (x_space) {
+    response.function_gradient(fnGradX, respFnCount);
+    if (taylorOrder == 2)
+      response.function_hessian(fnHessX, respFnCount);
+  }
+  else {
+    response.function_gradient(fnGradU, respFnCount);
+    if (taylorOrder == 2)
+      response.function_hessian(fnHessU, respFnCount);
+  }
+  IntResponsePair response_pr(0, response); // dummy eval id
+
+  // After a design variable change, history data (e.g., TANA) needs
+  // to be cleared (build_approximation() only calls clear_current())
+  if (numRelAnalyses && levelCount == 0)
+    uSpaceModel.approximations()[respFnCount].clear_all();
+  // build the new local/multipoint approximation
+  uSpaceModel.build_approximation(mpp_vars, response_pr);
+}
+
+
+void NonDLocalReliability::
+update_pma_maximize(const RealVector& mpp_u, const RealVector& fn_grad_u,
+		    const RealSymMatrix& fn_hess_u)
+{
+  Real p_cdf; bool update = false;
+  size_t rl_len  = requestedRespLevels[respFnCount].length(),
+    rl_pl_len    = rl_len + requestedProbLevels[respFnCount].length(),
+    rl_pl_bl_len = rl_pl_len + requestedRelLevels[respFnCount].length();
+  if (levelCount <  rl_pl_len) {
+    Real p = requestedProbLevels[respFnCount][levelCount-rl_len];
+    p_cdf = (cdfFlag) ? p : 1. - p;
+    update = true;
+  }
+  else if (levelCount >= rl_pl_bl_len) {
+    Real gen_beta = requestedGenRelLevels[respFnCount][levelCount-rl_pl_bl_len];
+    Real gen_beta_cdf = (cdfFlag) ? gen_beta : -gen_beta;
+    p_cdf = probability(gen_beta_cdf);
+    update = true;
+  }
+  if (update) {
+    Real beta_cdf = reliability(p_cdf, true, mpp_u, fn_grad_u, fn_hess_u);
+    pmaMaximizeG = (beta_cdf < 0.);
+  }
+}
+
+
+void NonDLocalReliability::assign_mean_data()
+{
+  const Pecos::RealVector& x_means = natafTransform.x_means();
+  mostProbPointX = x_means;
+  mostProbPointU = ranVarMeansU;
+  computedRespLevel = fnValsMeanX(respFnCount);
+  for (size_t i=0; i<numUncertainVars; i++)
+    fnGradX[i] = fnGradsMeanX(i,respFnCount);
+  SizetMultiArrayConstView cv_ids = iteratedModel.continuous_variable_ids();
+  SizetArray x_dvv; copy_data(cv_ids, x_dvv);
+  natafTransform.trans_grad_X_to_U(fnGradX, fnGradU, x_means, x_dvv, cv_ids);
+  if (taylorOrder == 2 && iteratedModel.hessian_type() != "quasi") {
+    fnHessX = fnHessiansMeanX[respFnCount];
+    natafTransform.trans_hess_X_to_U(fnHessX, fnHessU, x_means, fnGradX,
+				     x_dvv, cv_ids);
+    curvatureDataAvailable = true; kappaUpdated = false;
+  }
+}
+
+
+/** This function recasts a G(u) response set (already transformed and
+    approximated in other recursions) into an RIA objective function. */
+void NonDLocalReliability::
+RIA_objective_eval(const Variables& sub_model_vars,
+		   const Variables& recast_vars,
+		   const Response& sub_model_response,
+		   Response& recast_response)
+{
+  // ----------------------------------------
+  // The RIA objective function is (norm u)^2
+  // ----------------------------------------
+
+  short       asv_val = recast_response.active_set_request_vector()[0];
+  const RealVector& u = recast_vars.continuous_variables();
+  size_t i, num_vars = u.length();
+  if (asv_val & 1) {
+    Real f = 0.;
+    for (i=0; i<num_vars; i++)
+      f += std::pow(u[i], 2); // f = u'u
+    recast_response.function_value(f, 0);
+  }
+  if (asv_val & 2) {
+    RealVector grad_f = recast_response.function_gradient_view(0);
+    for (i=0; i<num_vars; ++i)
+      grad_f[i] = 2.*u[i]; // grad f = 2u
+  }
+  if (asv_val & 4) {
+    RealSymMatrix hess_f = recast_response.function_hessian_view(0);
+    hess_f = 0.;
+    for (i=0; i<num_vars; i++)
+      hess_f(i,i) = 2.; // hess f = 2's on diagonal
+  }
+
+  // Using f = norm u is a poor choice, since grad f is undefined at u = 0.
+  //Real sqrt_sum_sq = std::sqrt(sum_sq);
+  //if (sqrt_sum_sq > 0.)
+  //  grad_f[i] = u[i]/sqrt_sum_sq;
+  //else // gradient undefined at origin, use 0. to keep optimizer happy
+  //  grad_f[i] = 0.;
+}
+
+
+/** This function recasts a G(u) response set (already transformed and
+    approximated in other recursions) into an RIA equality constraint. */
+void NonDLocalReliability::
+RIA_constraint_eval(const Variables& sub_model_vars,
+		    const Variables& recast_vars,
+		    const Response& sub_model_response,
+		    Response& recast_response)
+{
+  // --------------------------------------------------------
+  // The RIA equality constraint is G(u) - response level = 0
+  // --------------------------------------------------------
+
+  short asv_val = recast_response.active_set_request_vector()[1];
+  int   resp_fn = nondLocRelInstance->respFnCount;
+  if (asv_val & 1) {
+    const Real& sub_model_fn = sub_model_response.function_value(resp_fn);
+    recast_response.function_value(
+      sub_model_fn - nondLocRelInstance->requestedTargetLevel, 1);
+  }
+  if (asv_val & 2) // dG/du: no additional transformation needed
+    recast_response.function_gradient(
+      sub_model_response.function_gradient_view(resp_fn), 1);
+  if (asv_val & 4) // d^2G/du^2: no additional transformation needed
+    recast_response.function_hessian(
+      sub_model_response.function_hessian(resp_fn), 1);
+}
+
+
+/** This function recasts a G(u) response set (already transformed and
+    approximated in other recursions) into an PMA objective function. */
+void NonDLocalReliability::
+PMA_objective_eval(const Variables& sub_model_vars,
+		   const Variables& recast_vars,
+		   const Response& sub_model_response,
+		   Response& recast_response)
+{
+  // ----------------------------------
+  // The PMA objective function is G(u)
+  // ----------------------------------
+
+  int   resp_fn    = nondLocRelInstance->respFnCount;
+  short sm_asv_val = sub_model_response.active_set_request_vector()[resp_fn];
+  Real fn; RealVector fn_grad_u; RealSymMatrix fn_hess_u;
+  if (sm_asv_val & 2)
+    fn_grad_u = sub_model_response.function_gradient_view(resp_fn);
+  if (sm_asv_val & 4)
+    fn_hess_u = sub_model_response.function_hessian_view(resp_fn);
+
+  // Due to RecastModel, objective_eval always called before constraint_eval,
+  // so perform NO_APPROX updates here.
+  if (nondLocRelInstance->mppSearchType == NO_APPROX &&
+      nondLocRelInstance->integrationOrder == 2) {
+    nondLocRelInstance->curvatureDataAvailable = true;
+    nondLocRelInstance->kappaUpdated = false; // new fn_{grad,hess}_u data
+    nondLocRelInstance->update_pma_maximize(recast_vars.continuous_variables(),
+					    fn_grad_u, fn_hess_u);
+  }
+
+  short asv_val = recast_response.active_set_request_vector()[0];
+  bool  pma_max = nondLocRelInstance->pmaMaximizeG;
+  if (asv_val & 1) {
+    fn = sub_model_response.function_value(resp_fn);
+    if (pma_max) recast_response.function_value(-fn, 0);
+    else         recast_response.function_value( fn, 0);
+  }
+  if (asv_val & 2) { // dG/du: no additional transformation needed
+    if (pma_max) {
+      RealVector recast_grad = recast_response.function_gradient_view(0);
+      size_t i, num_vars = fn_grad_u.length();
+      for (i=0; i<num_vars; ++i)
+	recast_grad[i] = -fn_grad_u[i];
+    }
+    else
+      recast_response.function_gradient(fn_grad_u, 0);
+  }
+  if (asv_val & 4) { // d^2G/du^2: no additional transformation needed
+    if (pma_max) {
+      RealSymMatrix recast_hess	= recast_response.function_hessian_view(0);
+      size_t i, j, num_vars = fn_hess_u.numRows();
+      for (i=0; i<num_vars; ++i)
+	for (j=0; j<=i; ++j)
+	  recast_hess(i,j) = -fn_hess_u(i,j);
+    }
+    else
+      recast_response.function_hessian(fn_hess_u, 0);
+  }
+
+#ifdef DEBUG
+  if (asv_val & 1)
+    Cout << "PMA_objective_eval(): sub-model function = " << fn << std::endl;
+  if (asv_val & 2) { // dG/du: no additional transformation needed
+    Cout << "PMA_objective_eval(): sub-model gradient:\n";
+    write_data(Cout, fn_grad_u);
+  }
+  if (asv_val & 4) { // d^2G/du^2: no additional transformation needed
+    Cout << "PMA_objective_eval(): sub-model Hessian:\n";
+    write_data(Cout, fn_hess_u, true, true, true);
+  }
+#endif // DEBUG
+}
+
+
+/** This function recasts a G(u) response set (already transformed and
+    approximated in other recursions) into a first-order PMA equality
+    constraint on reliability index beta. */
+void NonDLocalReliability::
+PMA_constraint_eval(const Variables& sub_model_vars,
+		    const Variables& recast_vars,
+		    const Response& sub_model_response,
+		    Response& recast_response)
+{
+  // ------------------------------------------------------
+  // The PMA equality constraint is (norm u)^2 - beta^2 = 0
+  // ------------------------------------------------------
+
+  short       asv_val = recast_response.active_set_request_vector()[1];
+  const RealVector& u = recast_vars.continuous_variables();
+  size_t i, num_vars = u.length();
+  if (asv_val & 1) {
+    // calculate the reliability index (beta)
+    Real beta_sq = 0.;
+    for (i=0; i<num_vars; ++i)
+      beta_sq += std::pow(u[i], 2); //use beta^2 to avoid singular grad @ origin
+    // calculate the equality constraint: u'u - beta_target^2
+    Real c = beta_sq - std::pow(nondLocRelInstance->requestedTargetLevel, 2);
+    recast_response.function_value(c, 1);
+  }
+  if (asv_val & 2) {
+    RealVector grad_f = recast_response.function_gradient_view(1);
+    for (i=0; i<num_vars; ++i)
+      grad_f[i] = 2.*u[i]; // grad f = 2u
+  }
+  if (asv_val & 4) {
+    RealSymMatrix hess_f = recast_response.function_hessian_view(1);
+    hess_f = 0.;
+    for (i=0; i<num_vars; i++)
+      hess_f(i,i) = 2.; // hess f = 2's on diagonal
+  }
+}
+
+
+/** This function recasts a G(u) response set (already transformed and
+    approximated in other recursions) into a second-order PMA equality
+    constraint on generalized reliability index beta-star. */
+void NonDLocalReliability::
+PMA2_constraint_eval(const Variables& sub_model_vars,
+		     const Variables& recast_vars,
+		     const Response& sub_model_response,
+		     Response& recast_response)
+{
+  // -----------------------------------------------------
+  // The PMA SORM equality constraint is beta* = beta*-bar
+  // -----------------------------------------------------
+
+  const RealVector& u = recast_vars.continuous_variables();
+  short    asv_val = recast_response.active_set_request_vector()[1];
+  int      resp_fn = nondLocRelInstance->respFnCount;
+  short sm_asv_val = sub_model_response.active_set_request_vector()[resp_fn];
+  bool         cdf = nondLocRelInstance->cdfFlag;
+
+  // Calculate beta --> p --> beta*.  Use up-to-date mpp/grad/Hessian info,
+  // including surrogate-based data, within signed_norm(), but disallow
+  // surrogate-based curvature corrections due to their sensitivity.  The
+  // presence of fn_grad_u/fn_hess_u data is enforced in PMA2_set_mapping().
+  RealVector fn_grad_u = sub_model_response.function_gradient_view(resp_fn);
+  Real comp_rel = nondLocRelInstance->computedRelLevel =
+    nondLocRelInstance->signed_norm(u, fn_grad_u, cdf);
+  // Don't update curvature correction when nonlinear transformation
+  // induces additional curvature on top of a low-order approximation.
+  // Note: if linear transformation or u-space AMV^2+, then Hessian is
+  // consistent with the previous truth and is constant over the surrogate.
+  Real computed_prob_level = (nondLocRelInstance->mppSearchType == NO_APPROX) ?
+    nondLocRelInstance->probability(comp_rel, cdf, u, fn_grad_u,
+      sub_model_response.function_hessian(resp_fn)) :
+    nondLocRelInstance->probability(comp_rel, cdf,
+      nondLocRelInstance->mostProbPointU, nondLocRelInstance->fnGradU,
+      nondLocRelInstance->fnHessU);
+  Real comp_gen_rel = nondLocRelInstance->computedGenRelLevel =
+    nondLocRelInstance->reliability(computed_prob_level);
+
+  if (asv_val & 1) { // calculate the equality constraint: beta* - bar-beta*
+    Real c = comp_gen_rel - nondLocRelInstance->requestedTargetLevel;
+#ifdef DEBUG
+    Cout << "In PMA2_constraint_eval, beta* = " << comp_gen_rel
+	 << " bar-beta* = " << nondLocRelInstance->requestedTargetLevel
+	 << " eq constr = " << c << std::endl;
+#endif
+    recast_response.function_value(c, 1);
+  }
+  if (asv_val & 2) {
+    // Note: for second-order integrations, beta* is a function of p and
+    // kappa(u).  dbeta*/du involves dkappa/du, but these terms are neglected
+    // as in dbeta*/ds (design sensitivities).
+    //   dbeta/du_i  = u_i/beta (in factor below)
+    //   dp_2/du_i   = [Phi(-beta_corr)*sum - phi(-beta_corr)*prod] * dbeta/du_i
+    //                 (term in brackets computed in dp2_dbeta_factor())
+    //   dbeta*/du_i = -1/phi(-beta*) * dp_2/du (in factor below)
+    Real factor = -nondLocRelInstance->dp2_dbeta_factor(comp_rel, cdf)
+                / comp_rel / Pecos::phi(-comp_gen_rel);
+    size_t i, num_vars = u.length();
+    RealVector grad_f = recast_response.function_gradient_view(1);
+    for (i=0; i<num_vars; ++i)
+      grad_f[i] = factor * u[i];
+#ifdef DEBUG
+    Cout << "In PMA2_constraint_eval, gradient of beta*:\n";
+    write_data(Cout, grad_f);
+#endif
+  }
+  if (asv_val & 4) {
+    Cerr << "Error: Hessian data not supported in NonDLocalReliability::"
+	 << "PMA2_constraint_eval()" << std::endl;
+    abort_handler(-1);
+    /*
+    RealSymMatrix hess_f = recast_response.function_hessian_view(1);
+    hess_f = 0.;
+    for (i=0; i<num_vars; i++)
+      hess_f(i,i) = ;
+    */
+  }
+}
+
+
+void NonDLocalReliability::
+PMA2_set_mapping(const Variables& recast_vars, const ActiveSet& recast_set,
+		 ActiveSet& sub_model_set)
+{
+  // if the constraint value/grad is requested for second-order PMA, then
+  // the sub-model response grad/Hessian are required to update beta*
+  short recast_request = recast_set.request_vector()[1];
+  if (recast_request & 3) { // value/grad request share beta-->p-->beta* calcs
+    int   sm_index          = nondLocRelInstance->respFnCount;
+    short sub_model_request = sub_model_set.request_value(sm_index);
+
+    // all cases require latest fn_grad_u (either truth-based or approx-based)
+    sub_model_request |= 2;
+    // PMA SORM requires latest fn_hess_u (truth-based)
+    if (nondLocRelInstance->mppSearchType == NO_APPROX)
+      sub_model_request |= 4;
+    // else value/grad request utilizes most recent truth fnGradU/fnHessU
+
+    sub_model_set.request_value(sub_model_request, sm_index);
+  }
+}
+
+
+/** Computes dg/ds where s = design variables.  Supports potentially
+    overlapping cases of design variable augmentation and insertion. */
+void NonDLocalReliability::
+dg_ds_eval(const RealVector& x_vars, const RealVector& fn_grad_x,
+	   RealVector& final_stat_grad)
+{
+  const SizetArray& final_dvv = finalStatistics.active_set_derivative_vector();
+  size_t i, num_final_grad_vars = final_dvv.size();
+  if (final_stat_grad.empty())
+    final_stat_grad.resize(num_final_grad_vars);
+
+  // For design vars that are distribution parameters of the uncertain vars,
+  // dg/ds = dg/dx * dx/ds where dx/ds is the design Jacobian.  Since dg/dx is
+  // already available (passed in as fn_grad_x), these sensitivities do not
+  // require additional response evaluations.
+  bool dist_param_deriv = false;
+  size_t num_outer_cv = secondaryACVarMapTargets.size();
+  for (i=0; i<num_outer_cv; i++)
+    if (secondaryACVarMapTargets[i] != Pecos::NO_TARGET) // dist param insertion
+      { dist_param_deriv = true; break; }
+  if (dist_param_deriv) {
+    SizetMultiArrayConstView cv_ids = iteratedModel.continuous_variable_ids();
+    SizetArray x_dvv; copy_data(cv_ids, x_dvv);
+    SizetMultiArrayConstView acv_ids
+      = iteratedModel.all_continuous_variable_ids();
+    RealVector fn_grad_s(num_final_grad_vars, false);
+    natafTransform.trans_grad_X_to_S(fn_grad_x, fn_grad_s, x_vars, x_dvv,
+				     cv_ids, acv_ids, primaryACVarMapIndices,
+				     secondaryACVarMapTargets);
+    final_stat_grad = fn_grad_s;
+  }
+
+  // For design vars that are separate from the uncertain vars, perform a new
+  // fn eval for dg/ds, where s = inactive/design vars.  This eval must be
+  // performed at (s, x_vars) for each response fn for each level as
+  // required by final_asv.  RBDO typically specifies one level for 1 or
+  // more limit states, so the number of additional evals will usually be small.
+  if (secondaryACVarMapTargets.empty() ||
+      contains(secondaryACVarMapTargets, Pecos::NO_TARGET)) {
+    Cout << "\n>>>>> Evaluating sensitivity with respect to augmented inactive "
+	 << "variables\n";
+    if (mppSearchType && mppSearchType < NO_APPROX)
+      uSpaceModel.component_parallel_mode(TRUTH_MODEL);
+    iteratedModel.continuous_variables(x_vars);
+    ActiveSet inactive_grad_set = activeSet;
+    inactive_grad_set.request_values(0);
+    inactive_grad_set.request_value(2, respFnCount);
+    // final_dvv is mapped from the top-level DVV in NestedModel::set_mapping()
+    // and includes augmented and inserted variable ids.  Since we only want the
+    // augmented ids in this case, the UQ-level inactive ids are sufficient.
+    SizetMultiArrayConstView icv_ids
+      = iteratedModel.inactive_continuous_variable_ids();
+    inactive_grad_set.derivative_vector(icv_ids);
+    /* More rigorous with reqd deriv vars, but equivalent in practice:
+    // Filter final_dvv to contain only inactive continuous variable ids:
+    SizetArray filtered_final_dvv;
+    for (i=0; i<num_final_grad_vars; i++) {
+      size_t final_dvv_i = final_dvv[i];
+      if (contains(icv_ids, final_dvv_i))
+	filtered_final_dvv.push_back(final_dvv_i);
+    }
+    inactive_grad_set.derivative_vector(filtered_final_dvv);
+    */
+    iteratedModel.compute_response(inactive_grad_set);
+    const Response& curr_resp = iteratedModel.current_response();
+    if (secondaryACVarMapTargets.empty())
+      final_stat_grad = curr_resp.function_gradient_copy(respFnCount);
+    else {
+      const RealMatrix& fn_grads = curr_resp.function_gradients();
+      size_t cntr = 0;
+      for (i=0; i<num_final_grad_vars; i++)
+	if (secondaryACVarMapTargets[i] == Pecos::NO_TARGET)
+	  final_stat_grad[i] = fn_grads(cntr++, respFnCount);
+    }
+  }
+}
+
+
+Real NonDLocalReliability::
+signed_norm(Real norm_mpp_u, const RealVector& mpp_u,
+	    const RealVector& fn_grad_u, bool cdf_flag)
+{
+  // z>median: CDF p(g<=z)>0.5, CDF beta<0, CCDF p(g>z)<0.5, CCDF beta>0
+  // z<median: CDF p(g<=z)<0.5, CDF beta>0, CCDF p(g>z)>0.5, CCDF beta<0
+  // z=median: CDF p(g<=z) = CCDF p(g>z) = 0.5, CDF beta = CCDF beta = 0
+  //Real beta_cdf = (computedRespLevel > medianFnVals[respFnCount])
+  //              ? -std::sqrt(norm_u_sq) : std::sqrt(norm_u_sq);
+
+  // This approach avoids the need to evaluate medianFnVals.  Thanks to
+  // Barron Bichon for suggesting it.
+  // if <mppU, fnGradU> > 0, then G is increasing along u and G(u*) > G(0)
+  // if <mppU, fnGradU> < 0, then G is decreasing along u and G(u*) < G(0)
+  Real beta_cdf = (mpp_u.dot(fn_grad_u) > 0.) ? -norm_mpp_u : norm_mpp_u;
+#ifdef DEBUG
+  Cout << "\nSign of <mppU, fnGradU> is ";
+  if (mpp_u.dot(fn_grad_u) > 0.) Cout << " 1.\n\n";
+  else                           Cout << "-1.\n\n";
+#endif
+  return (cdf_flag) ? beta_cdf : -beta_cdf;
+}
+
+
+/** Converts beta into a probability using either first-order (FORM) or
+    second-order (SORM) integration.  The SORM calculation first calculates
+    the principal curvatures at the MPP (using the approach in Ch. 8 of
+    Haldar & Mahadevan), and then applies correction formulations from the
+    literature (Breitung, Hohenbichler-Rackwitz, or Hong). */
+Real NonDLocalReliability::
+probability(Real beta, bool cdf_flag, const RealVector& mpp_u,
+	    const RealVector& fn_grad_u, const RealSymMatrix& fn_hess_u)
+{
+  Real p = probability(beta); // FORM approximation
+  int wpp7;
+  if (outputLevel > NORMAL_OUTPUT) {
+    wpp7 = write_precision+7;
+    Cout << "Probability:"// << " beta = " << beta
+	 << " first-order = " << std::setw(wpp7) << p;
+  }
+
+  if (integrationOrder == 2 && curvatureDataAvailable) {
+
+    if (!kappaUpdated) {
+      principal_curvatures(mpp_u, fn_grad_u, fn_hess_u, kappaU);
+      kappaUpdated = true;
+    }
+
+    // The correction to p is applied for beta >= 0 (FORM p <= 0.5).
+    // For beta < 0, apply correction to complementary problem (Tvedt 1990).
+    //   > beta changes sign
+    //   > p becomes complement
+    //   > principal curvature sign convention defined for CDF beta > 0
+    //     (negate for CDF beta < 0 or CCDF beta > 0, OK for CCDF beta < 0)
+    Real beta_corr = std::abs(beta);
+    Real p_corr    = (beta >= 0.) ? p : 1. - p;
+    RealVector kappa; scale_curvature(beta, cdf_flag, kappaU, kappa);
+
+    // Test for numerical exceptions in sqrt.  Problematic kappa are large and
+    // negative (kterm is always positive).  Skipping individual kappa means
+    // neglecting a primary curvature and including secondary curvatures, which
+    // may be counter-productive (potentially less accurate than FORM).
+    // Therefore, the entire correction is skipped if any curvature is
+    // problematic.  A consistent approach must be used in reliability().
+    bool apply_correction = true;
+    Real psi_m_beta;
+    if (secondOrderIntType != BREITUNG)
+      psi_m_beta = Pecos::phi(-beta_corr) / Pecos::Phi(-beta_corr);
+    Real kterm = (secondOrderIntType == BREITUNG) ? beta_corr : psi_m_beta;
+    int i, num_kappa = numUncertainVars - 1;
+    for (i=0; i<num_kappa; i++) {
+      //Cout << "1 + kterm*kappa = " << 1. + kterm * kappa[i] << std::endl;
+      // Numerical exception happens for 1+ktk <= 0., but inaccuracy can happen
+      // earlier.  Empirical evidence to date suggests a threshold of 0.5
+      // (1/std::sqrt(0.5) = 1.414 multiplier = 41.4% increase in p.
+      if (1. + kterm * kappa[i] <= curvatureThresh)
+	apply_correction = false;
+    }
+
+    if (apply_correction) {
+      // compute SORM estimate (Breitung, Hohenbichler-Rackwitz, or Hong).
+      Real C1 = 0., ktk;
+      for (i=0; i<num_kappa; i++) {
+	// Breitung 1984:              p_corr /= std::sqrt(1+beta_corr*kappa)
+	// Hohenbichler-Rackwitz 1988: p_corr /= std::sqrt(1+psi_m_beta*kappa)
+	// > Note that psi(-beta) -> beta as beta increases: HR -> Breitung
+	// Hong 1999, P3 formulation:  p_corr =  C1 * p_HR
+	ktk = kterm * kappa[i];
+	p_corr /= std::sqrt(1. + ktk);
+	if (secondOrderIntType == HONG) {
+	  Real hterm = num_kappa * kappa[i] / 2. / (1. + ktk);
+	  C1 += Pecos::Phi(-beta_corr-hterm) / Pecos::Phi(-beta_corr)
+	     *  exp(psi_m_beta*hterm);
+	}
+      }
+      if (secondOrderIntType == HONG) {
+	C1 /= num_kappa;
+	p_corr *= C1;
+      }
+      if (p_corr >= 0. && p_corr <= 1.) { // verify p_corr within valid range
+	p = (beta >= 0.) ? p_corr : 1. - p_corr;
+	if (outputLevel > NORMAL_OUTPUT)
+	  Cout << " second-order = " << std::setw(wpp7) << p;
+      }
+      else {
+	Cerr << "\nWarning: second-order probability integration bypassed due "
+	     << "to numerical issues (corrected p outside [0,1]).\n";
+	warningBits |= 2; // second warning in output summary
+      }
+    }
+    else {
+      Cerr << "\nWarning: second-order probability integration bypassed due "
+	   << "to numerical issues (curvature threshold exceeded).\n";
+      warningBits |= 2; // second warning in output summary
+    }
+  }
+
+  if (integrationRefinement) { // IS/AIS/MMAIS
+    // rep needed for access to functions not mapped to Iterator level
+    NonDAdaptImpSampling* importance_sampler_rep
+      = (NonDAdaptImpSampling*)importanceSampler.iterator_rep();
+    bool x_data_flag = false;
+    importance_sampler_rep->
+      initialize(mpp_u, x_data_flag, respFnCount, p, requestedTargetLevel);
+    ParLevLIter pl_iter = methodPCIter->mi_parallel_level_iterator(miPLIndex);
+    importanceSampler.run(pl_iter);
+    p = importance_sampler_rep->final_probability();
+    if (outputLevel > NORMAL_OUTPUT)
+      Cout << " refined = " << std::setw(wpp7) << p;
+  }
+  if (outputLevel > NORMAL_OUTPUT)
+    Cout << '\n';
+#ifdef DEBUG
+  if (integrationOrder == 2 && curvatureDataAvailable)
+    { Cout << "In probability(), kappaU:\n"; write_data(Cout, kappaU); }
+#endif
+
+  return p;
+}
+
+
+/** Compute sensitivity of second-order probability w.r.t. beta for use
+    in derivatives of p_2 or beta* w.r.t. auxilliary parameters s (design,
+    epistemic) or derivatives of beta* w.r.t. u in PMA2_constraint_eval(). */
+Real NonDLocalReliability::dp2_dbeta_factor(Real beta, bool cdf_flag)
+{
+  //   dp/ds     = -phi(-beta) * dbeta/ds
+  //               (fall back to first-order, if needed)
+  //   dp_2/ds   = [Phi(-beta_corr)*sum - phi(-beta_corr)*prod] * dbeta/ds
+  //               (this function computes term in brackets)
+  //   dbeta*/ds = -1/phi(-beta*) * dp_2/ds    (second-order)
+
+  // For beta < 0, beta_corr = -beta and p_corr = 1 - p:
+  // dp/ds = -dp_corr/ds = -(dp_corr/dbeta_corr * dbeta_corr/ds)
+  //       = -(dp_corr/dbeta_corr * -dbeta/ds)
+  //       = dp_corr/dbeta_corr * dbeta/ds
+
+  bool apply_correction; size_t i, j, num_kappa;
+  Real kterm, dpsi_m_beta_dbeta, beta_corr; RealVector kappa;
+  if (curvatureDataAvailable) {
+
+    //if (!kappaUpdated) { // should already be up to date
+    //  principal_curvatures(mpp_u, fn_grad_u, fn_hess_u, kappaU);
+    //  kappaUpdated = true;
+    //}
+
+    scale_curvature(beta, cdf_flag, kappaU, kappa);
+    beta_corr = (beta >= 0.) ? beta : -beta;
+
+    switch (secondOrderIntType) {
+    case HONG: // addtnl complexity not warranted
+      Cerr << "\nError: final statistic gradients not implemented for Hong."
+	   << std::endl;
+      abort_handler(-1); break;
+    case BREITUNG:
+      kterm = beta_corr; break;
+    case HOHENRACK:
+      // Psi(beta) = phi(beta) / Phi(beta)
+      // dPsi/dbeta = (Phi dphi/dbeta - phi^2)/Phi^2
+      //   where dphi/dbeta = -beta phi
+      // dPsi/dbeta = -phi (beta Phi + phi) / Phi^2
+      //            = -Psi (beta + Psi)
+      // --> dPsi/dbeta(-beta_corr)
+      //       = -Psi(-beta_corr) (-beta_corr + Psi(-beta_corr) )
+      //       =  Psi(-beta_corr) ( beta_corr - Psi(-beta_corr) )
+      kterm = Pecos::phi(-beta_corr) / Pecos::Phi(-beta_corr); // psi_m_beta
+      dpsi_m_beta_dbeta = kterm*(beta_corr - kterm); // orig (kterm + beta_corr)
+      break;
+    }
+
+    num_kappa = numUncertainVars - 1;
+    apply_correction = true;
+    for (i=0; i<num_kappa; ++i)
+      if (1. + kterm * kappa[i] <= curvatureThresh)
+	apply_correction = false;
+
+    if (apply_correction) {
+      Real sum = 0., ktk, prod1, prod2 = 1.;
+      for (i=0; i<num_kappa; ++i) {
+	ktk = kterm * kappa[i];
+	prod2 /= std::sqrt(1. + ktk);
+	prod1 = 1.;
+	for (j=0; j<num_kappa; ++j)
+	  if (j != i)
+	    prod1 /= std::sqrt(1. + kterm * kappa[j]);
+	prod1 *= kappa[i] / 2. / std::pow(1. + ktk, 1.5);
+	if (secondOrderIntType != BREITUNG)
+	  prod1 *= dpsi_m_beta_dbeta;
+	sum -= prod1;
+      }
+
+      // verify p_corr within (0,1) for consistency with probability()
+      Real p1_corr = probability(beta_corr), p2_corr = p1_corr * prod2;
+      if (p2_corr >= 0. && p2_corr <= 1.) // factor for second-order dp/ds:
+	return p1_corr * sum - Pecos::phi(-beta_corr) * prod2;
+    }
+
+    // if not returned, then there was an exception
+    Cerr << "\nWarning: second-order probability sensitivity bypassed.\n";
+    warningBits |= 2; // second warning in output summary
+  }
+
+  return -Pecos::phi(-beta);
+}
+
+
+// Converts a probability into a reliability using the inverse of the
+// first-order or second-order integrations implemented in
+// NonDLocalReliability::probability().
+Real NonDLocalReliability::
+reliability(Real p, bool cdf_flag, const RealVector& mpp_u,
+	    const RealVector& fn_grad_u, const RealSymMatrix& fn_hess_u)
+{
+  Real beta = reliability(p); // FORM approximation
+
+  if (integrationOrder == 2 && curvatureDataAvailable) {
+
+    if (!kappaUpdated) {
+      principal_curvatures(mpp_u, fn_grad_u, fn_hess_u, kappaU);
+      kappaUpdated = true;
+    }
+
+    // NOTE: these conversions are currently done once.  It may be necessary
+    // to redo them for each beta estimate (when inverting near beta = zero).
+    Real beta_corr = (beta >= 0.) ? beta : -beta;
+    Real p_corr    = (beta >= 0.) ? p    : 1. - p;
+    RealVector kappa; scale_curvature(beta, cdf_flag, kappaU, kappa);
+
+    // SORM correction to FORM: direct inversion of the SORM formulas is
+    // infeasible due to the multiple instances of beta on the RHS, even for
+    // the simplest case (Breitung).  Therefore, use Newton's method to solve
+    // for beta(p) using Phi_inverse() as an initial guess.
+    // > Newton's method uses reliability_residual() to compute the residual f
+    //   and reliability_residual_derivative() to compute df/dbeta.
+    // > Newton step is then beta -= f(beta)/[df/dbeta(beta)].
+    // > Other options include using an inexact df/dbeta = phi(-beta) from
+    //   FORM or using a quasi-Newton (Broyden update) or FD Newton approach.
+
+    // evaluate residual
+    Real res;
+    bool terminate = reliability_residual(p_corr, beta_corr, kappa, res);
+
+    size_t newton_iters = 0, max_iters = 20; // usually converges in ~3 iters
+    bool converged = false;
+    while (!terminate && !converged) {
+
+      // evaluate derivative of residual w.r.t. beta
+      Real dres_dbeta
+	= reliability_residual_derivative(p_corr, beta_corr, kappa);
+
+      // compute Newton step
+      Real delta_beta;
+      if (std::fabs(dres_dbeta) > DBL_MIN) {
+	delta_beta = -res/dres_dbeta; // full Newton step
+	// assess convergence using delta_beta, rather than residual,
+	// since this should be better scaled.
+	if (std::fabs(delta_beta) < convergenceTol)
+	  converged = true; // but go ahead and take the step, if beneficial
+      }
+      else
+	terminate = true;
+
+      // Simple backtracking line search globalization
+      bool reduction = false;
+      size_t backtrack_iters = 0;
+      while (!reduction && !terminate) { // enter loop even if converged
+	Real beta_step = beta_corr + delta_beta;
+
+	// verify that new beta_step doesn't violate safeguards.  If not,
+	// evaluate residual res_step at beta_step.
+	Real res_step;
+	terminate = reliability_residual(p_corr, beta_step, kappa, res_step);
+
+	if (!terminate) {
+	  if ( std::fabs(res_step) < std::fabs(res) ) { // accept step
+	    reduction = true;
+	    beta_corr = beta_step;
+	    res       = res_step;
+	    //Cout << "residual = " << res << " delta = " << delta_beta
+	    //     << " beta = " << beta_corr <<'\n';
+	  }
+	  else if (converged)
+	    terminate = true; // kick out of inner while
+	  else { // backtrack
+	    //Cout << "Backtracking\n";
+	    delta_beta /= 2.; // halve the step
+	    if (backtrack_iters++ >= max_iters) {// backtrack iter must complete
+	      Cerr << "\nWarning: maximum back-tracking iterations exceeded in "
+		   << "second-order reliability inversion.\n";
+	      warningBits |= 4; // third warning in output summary
+	      terminate = true;
+	    }
+	  }
+	}
+      }
+      if (++newton_iters >= max_iters && !converged) { // Newton iter completed
+	Cerr << "\nWarning: maximum Newton iterations exceeded in second-order "
+	     << "reliability inversion.\n";
+	warningBits |= 8; // fourth warning in output summary
+	terminate = true;
+      }
+    }
+    return (beta >= 0.) ? beta_corr : -beta_corr;
+  }
+  return beta;
+}
+
+
+bool NonDLocalReliability::
+reliability_residual(const Real& p, const Real& beta,
+		     const RealVector& kappa, Real& res)
+{
+  int i, num_kappa = numUncertainVars - 1;
+
+  // Test for numerical exceptions in sqrt.  Problematic kappa are large and
+  // negative (kterm is always positive).  Skipping individual kappa means
+  // neglecting a primary curvature and including secondary curvatures, which
+  // may be counter-productive (potentially less accurate than FORM).  Since
+  // the Newton solve can be problematic on its own, skip the entire solve in
+  // this case.
+  Real psi_m_beta;
+  if (secondOrderIntType != BREITUNG)
+    psi_m_beta = Pecos::phi(-beta) / Pecos::Phi(-beta);
+  Real kterm = (secondOrderIntType == BREITUNG) ? beta : psi_m_beta;
+  for (i=0; i<num_kappa; i++)
+    if (1. + kterm * kappa[i] <= curvatureThresh) {
+      Cerr << "\nWarning: second-order probability integration bypassed due to "
+	   << "numerical issues.\n";
+      warningBits |= 2; // second warning in output summary
+      return true;
+    }
+
+  // evaluate residual of f(beta,p) = 0 where p is a prescribed constant:
+  //   Breitung: f = 0 = p * Prod_i(sqrt(1+beta*kappa)) - Phi(-beta)
+  //   HohRack:  f = 0 = p * Prod_i(sqrt(1+psi(-beta)*kappa)) - Phi(-beta)
+  //   Hong:     f = 0 = p * Prod_i(sqrt(1+psi(-beta)*kappa)) - C1*Phi(-beta)
+  Real prod = 1., ktk, C1 = 0.;
+  for (i=0; i<num_kappa; i++) {
+    ktk = kterm * kappa[i];
+    prod *= std::sqrt(1. + ktk);
+    if (secondOrderIntType == HONG) {
+      Real hterm = num_kappa * kappa[i] / 2. / (1. + ktk);
+      C1 += Pecos::Phi(-beta - hterm) / Pecos::Phi(-beta)
+	 *  exp(psi_m_beta * hterm);
+    }
+  }
+  if (secondOrderIntType == HONG)
+    res = p * prod - C1 * Pecos::Phi(-beta);
+  else
+    res = p * prod - Pecos::Phi(-beta);
+
+  return false;
+}
+
+
+Real NonDLocalReliability::
+reliability_residual_derivative(const Real& p, const Real& beta,
+				const RealVector& kappa)
+{
+  int i, j, num_kappa = numUncertainVars - 1;
+  Real psi_m_beta, dpsi_m_beta_dbeta;
+  if (secondOrderIntType != BREITUNG) {
+    psi_m_beta = Pecos::phi(-beta) / Pecos::Phi(-beta);
+    dpsi_m_beta_dbeta = psi_m_beta*(beta + psi_m_beta);
+  }
+
+  // evaluate derivative of residual w.r.t. beta
+  Real prod, dres_dbeta, sum = 0.;
+  Real kterm = (secondOrderIntType == BREITUNG) ? beta : psi_m_beta;
+  for (i=0; i<num_kappa; i++) {
+    prod = 1.;
+    for (j=0; j<num_kappa; j++)
+      if (j != i)
+	prod *= std::sqrt(1. + kterm*kappa[j]);
+    prod *= kappa[i]/2./std::sqrt(1. + kterm*kappa[i]);
+    if (secondOrderIntType != BREITUNG)
+      prod *= dpsi_m_beta_dbeta;
+    sum += prod;
+  }
+  if (secondOrderIntType == HONG) { // addtnl complexity may not be warranted
+    Cerr << "\nError: reliability residual derivative not implemented for Hong."
+	 << std::endl;
+    abort_handler(-1);
+    //dres_dbeta = p * sum + C1 * phi(-beta) - Phi(-beta) * dC1_dbeta;
+  }
+  else
+    dres_dbeta = p * sum + Pecos::phi(-beta);
+
+  return dres_dbeta;
+}
+
+
+void NonDLocalReliability::
+principal_curvatures(const RealVector& mpp_u, const RealVector& fn_grad_u,
+		     const RealSymMatrix& fn_hess_u, RealVector& kappa_u)
+{
+  // fn_grad_u, fn_hess_u, and possibly mpp_u (alternate R0 initialization)
+  // must be in synch and be a reasonable approximation to converged MPP data.
+
+  // compute R matrix
+  int i, j, k, num_vars = mpp_u.length(), num_kappa = num_vars - 1;
+  RealMatrix R0(num_vars, num_vars);// init to 0
+  // initialize R0: last row values are direction cosines
+  for (i=0; i<num_kappa; i++)
+    R0(i, i) = 1.;
+  // Haldar & Mahadevan, p.227: last row = unit gradient vector of limit state
+  Real norm_grad_u = fn_grad_u.normFrobenius();
+  if (norm_grad_u > DBL_MIN)
+    for (i=0; i<num_vars; i++)
+      R0(num_kappa, i) = fn_grad_u[i]/norm_grad_u;
+  else { // fallback: try to use +/- mPPU[i]/norm(mPPU)
+    Real norm_mpp_u = mpp_u.normFrobenius(); // unsigned beta
+    if (norm_mpp_u > DBL_MIN) {
+      // Can match the sign of fn_grad_u[i]/norm_grad_u in PMA case (align for
+      // max G, oppose for min G), but can't in general in RIA case (vectors
+      // may align or oppose).  Fortunately, the R0 sign does not appear to
+      // matter since R is applied twice in R fn_hess_u R^T.
+      bool pma_max = (levelCount >= requestedRespLevels[respFnCount].length() &&
+		      pmaMaximizeG) ? true : false;
+      for (i=0; i<num_vars; i++)
+	R0(num_kappa, i) = (pma_max) ?  mpp_u[i]/norm_mpp_u  // aligned
+	                             : -mpp_u[i]/norm_mpp_u; // opposed
+    }
+    else {
+      // Note: for Breitung, kappa_i do not matter if beta = 0.
+      Cerr << "\nError: unable to initialize R0 in principal_curvatures() "
+	   << "calculation." << std::endl;
+      abort_handler(-1);
+    }
+  }
+  //Cout << "\nR0:" << R0;
+
+  // orthogonalize using Gram-Schmidt
+  RealMatrix R(R0);
+  for (i=num_vars-2; i>=0; i--) {  // update the ith row vector
+    for (j=i+1; j<num_vars; j++) { // orthogonalize to jth row vector
+      Real scale1 = 0., scale2 = 0.;
+      for (k=0; k<num_vars; k++) { // kth column
+	scale1 += R(j, k) * R0(i, k);
+	scale2 += std::pow(R(j, k), 2);
+      }
+      Real scale = scale1 / scale2;
+      for (k=0; k<num_vars; k++)   // kth column
+	R(i, k) -= scale * R(j, k);
+    }
+    // renormalize ith row vector to unit length
+    Real len = 0.;
+    for (j=0; j<num_vars; j++)
+      len += std::pow(R(i, j), 2);
+    len = std::sqrt(len);
+    for (j=0; j<num_vars; j++)
+      R(i, j) /= len;
+  }
+  //Cout << "\nR:" << R;
+
+  // compute A matrix = (R fn_hess_u R^T)/norm(fn_grad_u)
+  RealSymMatrix A(num_vars, false);
+  Teuchos::symMatTripleProduct(Teuchos::NO_TRANS, 1./norm_grad_u, fn_hess_u,
+			       R, A);
+  //Cout << "\nA:" << A;
+  A.reshape(num_kappa); // upper left portion of matrix
+  //Cout << "\nReshaped A:" << A;
+
+  // compute eigenvalues of A --> principal curvatures
+  Teuchos::LAPACK<int, Real> la;
+  int info, lwork = 3*num_kappa - 1;
+  double* work = new double [lwork];
+  // LAPACK eigenvalue solution for real, symmetric A
+  if (kappa_u.length() != num_kappa)
+    kappa_u.sizeUninitialized(num_kappa);
+  la.SYEV('N', A.UPLO(), num_kappa, A.values(), A.stride(), kappa_u.values(),
+	  work, lwork, &info);
+  delete [] work;
+  if (info) {
+    Cerr << "\nError: internal error in LAPACK eigenvalue routine."
+         << std::endl;
+    abort_handler(-1);
+  }
+  //Cout << "\nkappa_u:" << kappa_u;
+}
+
+
+void NonDLocalReliability::print_results(std::ostream& s)
+{
+  size_t i, j, width = write_precision+7;
+  StringMultiArrayConstView uv_labels
+    = iteratedModel.continuous_variable_labels();
+  const StringArray& fn_labels = iteratedModel.response_labels();
+  s << "-----------------------------------------------------------------\n";
+
+  if (warningBits) {
+    s << "Warnings accumulated during solution for one or more levels:\n";
+    if (warningBits & 1)
+      s << "  Maximum number of limit state approximation cycles exceeded.\n";
+    if (warningBits & 2)
+      s << "  Second-order probability integration bypassed due to numerical "
+	<< "issues.\n";
+    if (warningBits & 4)
+      s << "  Maximum back-tracking iterations exceeded in second-order "
+	<< "reliability inversion.\n";
+    if (warningBits & 8)
+      s << "  Maximum Newton iterations exceeded in second-order reliability "
+	<< "inversion.\n";
+    s << "Please interpret results with care.\n";
+    s << "-----------------------------------------------------------------\n";
+  }
+
+  for (i=0; i<numFunctions; i++) {
+
+    // output MV-specific statistics
+    if (!mppSearchType) {
+      s << "MV Statistics for " << fn_labels[i] << ":\n";
+      // approximate response means and std deviations and importance factors
+      Real& std_dev = momentStats(1,i);
+      s << "  Approximate Mean Response                  = " << std::setw(width)
+	<< momentStats(0,i) << "\n  Approximate Standard Deviation of Response"
+	<< " = " << std::setw(width)<< std_dev << '\n';
+      if (natafTransform.x_correlation() || std_dev < Pecos::SMALL_NUMBER)
+	s << "  Importance Factors not available.\n";
+      else
+	for (j=0; j<numUncertainVars; j++)
+	  s << "  Importance Factor for variable "
+	    << std::setiosflags(std::ios::left) << std::setw(11)
+	    << uv_labels[j].data() << " = "
+	    << std::resetiosflags(std::ios::adjustfield)
+	    << std::setw(width) << impFactor(j,i)
+      // Added sensitivity output to importance factors
+      << "  Sensitivity = "
+      << std::resetiosflags(std::ios::adjustfield)
+      << std::setw(width) << fnGradsMeanX(j,i) << '\n';
+    }
+
+    // output CDF/CCDF response/probability pairs
+    size_t num_levels = computedRespLevels[i].length();
+    if (num_levels) {
+      if (!mppSearchType && momentStats(1,i) < Pecos::SMALL_NUMBER)
+        s << "\nWarning: negligible standard deviation renders CDF results "
+          << "suspect.\n\n";
+      if (cdfFlag)
+        s << "Cumulative Distribution Function (CDF) for ";
+      else
+        s << "Complementary Cumulative Distribution Function (CCDF) for ";
+
+      s << fn_labels[i] << ":\n     Response Level  Probability Level  "
+	<< "Reliability Index  General Rel Index\n     --------------  "
+	<< "-----------------  -----------------  -----------------\n";
+      for (j=0; j<num_levels; j++)
+        s << "  " << std::setw(width) << computedRespLevels[i][j]
+	  << "  " << std::setw(width) << computedProbLevels[i][j]
+	  << "  " << std::setw(width) << computedRelLevels[i][j]
+	  << "  " << std::setw(width) << computedGenRelLevels[i][j] << '\n';
+    }
+  }
+
+  //s << "Final statistics:\n" << finalStatistics;
+
+  s << "-----------------------------------------------------------------"
+    << std::endl;
+}
+
+
+void NonDLocalReliability::method_recourse()
+{
+  Cerr << "\nWarning: method recourse invoked in NonDLocalReliability due to "
+       << "detected method conflict.\n\n";
+  if (mppSearchType && npsolFlag) {
+#ifdef HAVE_OPTPP
+    mppOptimizer.assign_rep(
+      new SNLLOptimizer("optpp_q_newton", mppModel), false);
+#else
+    Cerr << "\nError: method recourse not possible in NonDLocalReliability "
+	 << "(OPT++ NIP unavailable).\n";
+    abort_handler(-1);
+#endif
+    npsolFlag = false;
+  }
+}
+
+} // namespace Dakota
Index: /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/NonDSampling.cpp
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/NonDSampling.cpp	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/configs/6.2/linux/src/NonDSampling.cpp	(revision 24593)
@@ -0,0 +1,1389 @@
+/*  _______________________________________________________________________
+
+    DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
+    Copyright 2014 Sandia Corporation.
+    This software is distributed under the GNU Lesser General Public License.
+    For more information, see the README file in the top Dakota directory.
+    _______________________________________________________________________ */
+
+//- Class:	 NonDSampling
+//- Description: Implementation code for NonDSampling class
+//- Owner:       Mike Eldred
+//- Checked by:
+//- Version:
+
+#include "dakota_data_types.hpp"
+#include "dakota_system_defs.hpp"
+#include "DakotaModel.hpp"
+#include "DakotaResponse.hpp"
+#include "NonDSampling.hpp"
+#include "ProblemDescDB.hpp"
+#include "SensAnalysisGlobal.hpp"
+#include "pecos_data_types.hpp"
+#include "pecos_stat_util.hpp"
+#include <algorithm>
+
+#include <boost/math/special_functions/fpclassify.hpp>
+
+static const char rcsId[]="@(#) $Id: NonDSampling.cpp 7036 2010-10-22 23:20:24Z mseldre $";
+
+
+namespace Dakota {
+
+
+/** This constructor is called for a standard letter-envelope iterator
+    instantiation.  In this case, set_db_list_nodes has been called and
+    probDescDB can be queried for settings from the method specification. */
+NonDSampling::NonDSampling(ProblemDescDB& problem_db, Model& model):
+  NonD(problem_db, model), seedSpec(probDescDB.get_int("method.random_seed")),
+  randomSeed(seedSpec), samplesSpec(probDescDB.get_int("method.samples")),
+  samplesRef(samplesSpec), numSamples(samplesSpec),
+  rngName(probDescDB.get_string("method.random_number_generator")),
+  sampleType(probDescDB.get_ushort("method.sample_type")),
+  statsFlag(true), allDataFlag(false), samplingVarsMode(ACTIVE),
+  sampleRanksMode(IGNORE_RANKS),
+  varyPattern(!probDescDB.get_bool("method.fixed_seed")),
+  backfillFlag(probDescDB.get_bool("method.backfill")),
+  numLHSRuns(0)
+{
+  if (epistemicStats && totalLevelRequests) {
+    Cerr << "\nError: sampling does not support level requests for "
+	 << "analyses containing epistemic uncertainties." << std::endl;
+    abort_handler(-1);
+  }
+
+  // Since the sampleType is shared with other iterators for other purposes,
+  // its default in DataMethod.cpp is SUBMETHOD_DEFAULT (0).  Enforce an LHS
+  // default here.
+  if (!sampleType)
+    sampleType = SUBMETHOD_LHS;
+
+  // initialize finalStatistics using the default statistics set
+  initialize_final_statistics();
+
+  // update concurrency
+  if (numSamples) // samples is optional (default = 0)
+    maxEvalConcurrency *= numSamples;
+}
+
+
+/** This alternate constructor is used for generation and evaluation
+    of on-the-fly sample sets. */
+NonDSampling::
+NonDSampling(unsigned short method_name, Model& model,
+	     unsigned short sample_type, int samples, int seed,
+	     const String& rng, bool vary_pattern, short sampling_vars_mode):
+  NonD(method_name, model), seedSpec(seed), randomSeed(seed),
+  samplesSpec(samples), samplesRef(samples), numSamples(samples), rngName(rng),
+  sampleType(sample_type), statsFlag(false), allDataFlag(true),
+  samplingVarsMode(sampling_vars_mode), sampleRanksMode(IGNORE_RANKS),
+  varyPattern(vary_pattern), backfillFlag(false), numLHSRuns(0)
+{
+  subIteratorFlag = true; // suppress some output
+
+  // override default epistemicStats setting from NonD ctor
+  bool aleatory_mode = (samplingVarsMode == ALEATORY_UNCERTAIN ||
+			samplingVarsMode == ALEATORY_UNCERTAIN_UNIFORM);
+  epistemicStats = (numEpistemicUncVars && !aleatory_mode);
+
+  // enforce LHS as default sample type
+  if (!sampleType)
+    sampleType = SUBMETHOD_LHS;
+
+  // not used but included for completeness
+  if (numSamples) // samples is optional (default = 0)
+    maxEvalConcurrency *= numSamples;
+}
+
+
+/** This alternate constructor is used by ConcurrentStrategy for
+    generation of uniform, uncorrelated sample sets. */
+NonDSampling::
+NonDSampling(unsigned short sample_type, int samples, int seed,
+	     const String& rng, const RealVector& lower_bnds,
+	     const RealVector& upper_bnds):
+  NonD(RANDOM_SAMPLING, lower_bnds, upper_bnds), seedSpec(seed),
+  randomSeed(seed), samplesSpec(samples), samplesRef(samples),
+  numSamples(samples), rngName(rng), sampleType(sample_type), statsFlag(false),
+  allDataFlag(true), samplingVarsMode(ACTIVE_UNIFORM),
+  sampleRanksMode(IGNORE_RANKS), varyPattern(true), backfillFlag(false),
+  numLHSRuns(0)
+{
+  subIteratorFlag = true; // suppress some output
+
+  // enforce LHS as default sample type
+  if (!sampleType)
+    sampleType = SUBMETHOD_LHS;
+
+  // not used but included for completeness
+  if (numSamples) // samples is optional (default = 0)
+    maxEvalConcurrency *= numSamples;
+}
+
+
+NonDSampling::~NonDSampling()
+{ }
+
+
+/** This version of get_parameter_sets() extracts data from the
+    user-defined model in any of the four sampling modes. */
+void NonDSampling::get_parameter_sets(Model& model)
+{
+  initialize_lhs(true);
+
+  short model_view = model.current_variables().view().first;
+  switch (samplingVarsMode) {
+  case ACTIVE_UNIFORM: case ALL_UNIFORM: case UNCERTAIN_UNIFORM:
+  case ALEATORY_UNCERTAIN_UNIFORM: case EPISTEMIC_UNCERTAIN_UNIFORM:
+    // Use LHSDriver::generate_uniform_samples() between lower/upper bounds
+    if ( samplingVarsMode == ACTIVE_UNIFORM ||
+	 ( samplingVarsMode == ALL_UNIFORM &&
+	   ( model_view == RELAXED_ALL || model_view == MIXED_ALL ) ) ||
+	 ( samplingVarsMode == UNCERTAIN_UNIFORM &&
+	   ( model_view == RELAXED_UNCERTAIN ||
+	     model_view == MIXED_UNCERTAIN ) ) ||
+	 ( samplingVarsMode == ALEATORY_UNCERTAIN_UNIFORM &&
+	   ( model_view == RELAXED_ALEATORY_UNCERTAIN ||
+	     model_view == MIXED_ALEATORY_UNCERTAIN ) ) ||
+	 ( samplingVarsMode == EPISTEMIC_UNCERTAIN_UNIFORM &&
+	   ( model_view == RELAXED_EPISTEMIC_UNCERTAIN ||
+	     model_view == MIXED_EPISTEMIC_UNCERTAIN ) ) ) {
+      // sample uniformly from ACTIVE lower/upper bounds (regardless of model
+      // view), from UNCERTAIN lower/upper bounds (with model in DISTINCT view),
+      // or from ALL lower/upper bounds (with model in ALL view).
+      // loss of sampleRanks control is OK since NonDIncremLHS uses ACTIVE mode.
+      // TO DO: add support for uniform discrete
+      lhsDriver.generate_uniform_samples(model.continuous_lower_bounds(),
+					 model.continuous_upper_bounds(),
+					 numSamples, allSamples, backfillFlag);
+    }
+    else if (samplingVarsMode == ALL_UNIFORM) {
+      // sample uniformly from ALL lower/upper bnds with model in distinct view.
+      // loss of sampleRanks control is OK since NonDIncremLHS uses ACTIVE mode.
+      // TO DO: add support for uniform discrete
+      lhsDriver.generate_uniform_samples(model.all_continuous_lower_bounds(),
+					 model.all_continuous_upper_bounds(),
+					 numSamples, allSamples, backfillFlag);
+    }
+    else { // A, E, A+E UNCERTAIN
+      // sample uniformly from {A,E,A+E} UNCERTAIN lower/upper bounds
+      // with model using a non-corresponding view (corresponding views
+      // handled in first case above)
+      size_t start_acv, num_acv, dummy;
+      mode_counts(model, start_acv, num_acv, dummy, dummy, dummy, dummy,
+		  dummy, dummy);
+      if (!num_acv) {
+	Cerr << "Error: no active continuous variables for sampling in "
+	     << "uniform mode" << std::endl;
+	abort_handler(-1);
+      }
+      const RealVector& all_c_l_bnds = model.all_continuous_lower_bounds();
+      const RealVector& all_c_u_bnds = model.all_continuous_upper_bounds();
+      RealVector uncertain_c_l_bnds(Teuchos::View,
+	const_cast<Real*>(&all_c_l_bnds[start_acv]), num_acv);
+      RealVector uncertain_c_u_bnds(Teuchos::View,
+	const_cast<Real*>(&all_c_u_bnds[start_acv]), num_acv);
+      // loss of sampleRanks control is OK since NonDIncremLHS uses ACTIVE mode
+      // TO DO: add support for uniform discrete
+      lhsDriver.generate_uniform_samples(uncertain_c_l_bnds,
+					 uncertain_c_u_bnds,
+					 numSamples, allSamples, backfillFlag);
+    }
+    break;
+  case ALEATORY_UNCERTAIN:
+    {
+      lhsDriver.generate_samples(model.aleatory_distribution_parameters(),
+				 numSamples, allSamples, backfillFlag);
+      break;
+    }
+  case EPISTEMIC_UNCERTAIN:
+    {
+      lhsDriver.generate_samples(model.epistemic_distribution_parameters(),
+				 numSamples, allSamples, backfillFlag);
+      break;
+    }
+  case UNCERTAIN:
+    {
+      lhsDriver.generate_samples(model.aleatory_distribution_parameters(),
+				 model.epistemic_distribution_parameters(),
+				 numSamples, allSamples, backfillFlag);
+      break;
+    }
+  case ACTIVE: case ALL: {
+    // extract design and state bounds
+    RealVector  cdv_l_bnds,   cdv_u_bnds,   csv_l_bnds,   csv_u_bnds;
+    IntVector ddriv_l_bnds, ddriv_u_bnds, dsriv_l_bnds, dsriv_u_bnds;
+    const RealVector& all_c_l_bnds = model.all_continuous_lower_bounds();
+    const RealVector& all_c_u_bnds = model.all_continuous_upper_bounds();
+    if (numContDesVars) {
+      cdv_l_bnds
+	= RealVector(Teuchos::View, all_c_l_bnds.values(), numContDesVars);
+      cdv_u_bnds
+	= RealVector(Teuchos::View, all_c_u_bnds.values(), numContDesVars);
+    }
+    if (numContStateVars) {
+      size_t cv_start = model.acv() - numContStateVars;
+      csv_l_bnds = RealVector(Teuchos::View,
+	const_cast<Real*>(&all_c_l_bnds[cv_start]), numContStateVars);
+      csv_u_bnds = RealVector(Teuchos::View,
+	const_cast<Real*>(&all_c_u_bnds[cv_start]), numContStateVars);
+    }
+    const IntVector& all_di_l_bnds = model.all_discrete_int_lower_bounds();
+    const IntVector& all_di_u_bnds = model.all_discrete_int_upper_bounds();
+    size_t num_ddriv = (numDiscIntDesVars) ?
+      numDiscIntDesVars - model.discrete_design_set_int_values().size() : 0;
+    if (num_ddriv) {
+      ddriv_l_bnds = IntVector(Teuchos::View, all_di_l_bnds.values(),num_ddriv);
+      ddriv_u_bnds = IntVector(Teuchos::View, all_di_u_bnds.values(),num_ddriv);
+    }
+    size_t num_dsriv = (numDiscIntStateVars) ?
+      numDiscIntStateVars - model.discrete_state_set_int_values().size() : 0;
+    if (num_dsriv) {
+      size_t di_start = model.adiv() - numDiscIntStateVars;
+      dsriv_l_bnds = IntVector(Teuchos::View,
+	const_cast<int*>(&all_di_l_bnds[di_start]), num_dsriv);
+      dsriv_u_bnds = IntVector(Teuchos::View,
+	const_cast<int*>(&all_di_u_bnds[di_start]), num_dsriv);
+    }
+    IntSetArray empty_isa; StringSetArray empty_ssa; RealSetArray empty_rsa;
+    const IntSetArray&    di_design_sets = (numDiscIntDesVars) ?
+      model.discrete_design_set_int_values()    : empty_isa;
+    const StringSetArray& ds_design_sets = (numDiscStringDesVars) ?
+      model.discrete_design_set_string_values() : empty_ssa;
+    const RealSetArray&   dr_design_sets = (numDiscRealDesVars) ?
+      model.discrete_design_set_real_values()   : empty_rsa;
+    const IntSetArray&    di_state_sets  = (numDiscIntStateVars) ?
+      model.discrete_state_set_int_values()     : empty_isa;
+    const StringSetArray& ds_state_sets  = (numDiscStringStateVars) ?
+      model.discrete_state_set_string_values()  : empty_ssa;
+    const RealSetArray&   dr_state_sets  = (numDiscRealStateVars) ?
+      model.discrete_state_set_real_values()    : empty_rsa;
+
+    // Call LHS to generate the specified samples within the specified
+    // distributions.  Use model distribution parameters unless ACTIVE
+    // excludes {aleatory,epistemic,both} uncertain variables.
+    if ( samplingVarsMode == ACTIVE &&
+	 ( model_view == RELAXED_DESIGN || model_view == RELAXED_STATE ||
+	   model_view ==   MIXED_DESIGN || model_view ==   MIXED_STATE ) ) {
+      Pecos::AleatoryDistParams empty_adp; Pecos::EpistemicDistParams empty_edp;
+      if ( !backfillFlag )
+	lhsDriver.generate_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+   	  ds_state_sets, dr_state_sets, empty_adp, empty_edp, numSamples,
+	  allSamples, sampleRanks);
+      else
+	lhsDriver.generate_unique_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+   	  ds_state_sets, dr_state_sets, empty_adp, empty_edp, numSamples,
+	  allSamples, sampleRanks);
+    }
+    else if ( samplingVarsMode == ACTIVE &&
+	      ( model_view == RELAXED_ALEATORY_UNCERTAIN ||
+		model_view == MIXED_ALEATORY_UNCERTAIN ) ) {
+      Pecos::EpistemicDistParams empty_edp;
+      if ( !backfillFlag )
+	lhsDriver.generate_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+  	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+	  ds_state_sets, dr_state_sets, model.aleatory_distribution_parameters(),
+	  empty_edp, numSamples, allSamples, sampleRanks);
+      else
+	lhsDriver.generate_unique_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+  	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+	  ds_state_sets, dr_state_sets, model.aleatory_distribution_parameters(),
+	  empty_edp, numSamples, allSamples, sampleRanks);
+    }
+    else if ( samplingVarsMode == ACTIVE &&
+	      ( model_view == RELAXED_EPISTEMIC_UNCERTAIN ||
+		model_view == MIXED_EPISTEMIC_UNCERTAIN ) ) {
+      Pecos::AleatoryDistParams empty_adp;
+      if ( !backfillFlag )
+	lhsDriver.generate_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+  	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+	  ds_state_sets, dr_state_sets, empty_adp,
+	  model.epistemic_distribution_parameters(), numSamples, allSamples,
+	  sampleRanks);
+      else
+	lhsDriver.generate_unique_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+  	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+	  ds_state_sets, dr_state_sets, empty_adp,
+	  model.epistemic_distribution_parameters(), numSamples, allSamples,
+	  sampleRanks);
+    }
+    else
+      {
+	if ( !backfillFlag )
+	  lhsDriver.generate_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+	  ds_state_sets, dr_state_sets, model.aleatory_distribution_parameters(),
+	  model.epistemic_distribution_parameters(), numSamples, allSamples,
+	  sampleRanks);
+	else
+	  lhsDriver.generate_unique_samples(cdv_l_bnds, cdv_u_bnds, ddriv_l_bnds,
+	  ddriv_u_bnds, di_design_sets, ds_design_sets, dr_design_sets,
+	  csv_l_bnds, csv_u_bnds, dsriv_l_bnds, dsriv_u_bnds, di_state_sets,
+	  ds_state_sets, dr_state_sets, model.aleatory_distribution_parameters(),
+	  model.epistemic_distribution_parameters(), numSamples, allSamples,
+	  sampleRanks);
+	  // warning sampleRanks will empty.
+	  // See comment in lhs_driver.cpp generate_unique_samples()
+      }
+    break;
+  }
+  }
+}
+
+
+/** This version of get_parameter_sets() does not extract data from the
+    user-defined model, but instead relies on the incoming bounded region
+    definition.  It only support a UNIFORM sampling mode, where the
+    distinction of ACTIVE_UNIFORM vs. ALL_UNIFORM is handled elsewhere. */
+void NonDSampling::
+get_parameter_sets(const RealVector& lower_bnds,
+		   const RealVector& upper_bnds)
+{
+  initialize_lhs(true);
+  lhsDriver.generate_uniform_samples(lower_bnds, upper_bnds,
+				     numSamples, allSamples);
+}
+
+
+void NonDSampling::
+update_model_from_sample(Model& model, const Real* sample_vars)
+{
+  size_t i, cntr = 0, cv_start, num_cv, div_start, num_div, dsv_start, num_dsv,
+    drv_start, num_drv;
+  mode_counts(model, cv_start, num_cv, div_start, num_div, dsv_start, num_dsv,
+	      drv_start, num_drv);
+
+  // sampled continuous vars (by value)
+  size_t end = cv_start + num_cv;
+  for (i=cv_start; i<end; ++i, ++cntr)
+    model.all_continuous_variable(sample_vars[cntr], i);
+  // sampled discrete int vars (by value cast from Real)
+  end = div_start + num_div;
+  for (i=div_start; i<end; ++i, ++cntr)
+    model.all_discrete_int_variable((int)sample_vars[cntr], i);
+  // sampled discrete string vars (by index cast from Real)
+  short active_view = model.current_variables().view().first;
+  bool relax = (active_view == RELAXED_ALL ||
+    ( active_view >= RELAXED_DESIGN && active_view <= RELAXED_STATE ) );
+  short all_view = (relax) ? RELAXED_ALL : MIXED_ALL;
+  const StringSetArray& all_dss_values
+    = model.discrete_set_string_values(all_view);
+  end = dsv_start + num_dsv;
+  for (i=dsv_start; i<end; ++i, ++cntr)
+    model.all_discrete_string_variable(set_index_to_value(
+      (size_t)sample_vars[cntr], all_dss_values[i]), i);
+  // sampled discrete real vars (by value)
+  end = drv_start + num_drv;
+  for (i=drv_start; i<end; ++i, ++cntr)
+    model.all_discrete_real_variable(sample_vars[cntr], i);
+}
+
+
+// BMA TODO: consolidate with other use cases
+void NonDSampling::
+sample_to_variables(const Real* sample_vars, Variables& vars)
+{
+  size_t i, cntr = 0, cv_start, num_cv, div_start, num_div, dsv_start, num_dsv,
+    drv_start, num_drv;
+  mode_counts(iteratedModel, cv_start, num_cv, div_start, num_div, dsv_start, num_dsv,
+	      drv_start, num_drv);
+
+  // BMA TODO: make sure inactive get updated too as needed?
+
+  // sampled continuous vars (by value)
+  size_t end = cv_start + num_cv;
+  for (i=cv_start; i<end; ++i, ++cntr)
+    vars.all_continuous_variable(sample_vars[cntr], i);
+  // sampled discrete int vars (by value cast from Real)
+  end = div_start + num_div;
+  for (i=div_start; i<end; ++i, ++cntr)
+    vars.all_discrete_int_variable((int)sample_vars[cntr], i);
+  // sampled discrete string vars (by index cast from Real)
+  short active_view = vars.view().first;
+  bool relax = (active_view == RELAXED_ALL ||
+    ( active_view >= RELAXED_DESIGN && active_view <= RELAXED_STATE ) );
+  short all_view = (relax) ? RELAXED_ALL : MIXED_ALL;
+  const StringSetArray& all_dss_values
+    = iteratedModel.discrete_set_string_values(all_view);
+  end = dsv_start + num_dsv;
+  for (i=dsv_start; i<end; ++i, ++cntr)
+    vars.all_discrete_string_variable(set_index_to_value(
+      (size_t)sample_vars[cntr], all_dss_values[i]), i);
+  // sampled discrete real vars (by value)
+  end = drv_start + num_drv;
+  for (i=drv_start; i<end; ++i, ++cntr)
+    vars.all_discrete_real_variable(sample_vars[cntr], i);
+}
+
+
+// BMA TODO: consolidate with other use cases
+/** Map the active variables from vars to sample_vars (column in allSamples) */
+void NonDSampling::
+variables_to_sample(const Variables& vars, Real* sample_vars)
+{
+  size_t cntr = 0;
+
+  const RealVector& c_vars = vars.continuous_variables();
+  for (size_t j=0; j<numContinuousVars; ++j, ++cntr)
+    sample_vars[cntr] = c_vars[j]; // jth row of samples_matrix
+
+  const IntVector& di_vars = vars.discrete_int_variables();
+  for (size_t j=0; j<numDiscreteIntVars; ++j, ++cntr)
+    sample_vars[cntr] = (Real) di_vars[j]; // jth row of samples_matrix
+
+  // to help with mapping string variables
+  // sampled discrete string vars (by index cast from Real)
+  short active_view = vars.view().first;
+  bool relax = (active_view == RELAXED_ALL ||
+    ( active_view >= RELAXED_DESIGN && active_view <= RELAXED_STATE ) );
+  short all_view = (relax) ? RELAXED_ALL : MIXED_ALL;
+  const StringSetArray& all_dss_values
+    = iteratedModel.discrete_set_string_values(all_view);
+
+  // is care needed to manage active vs. all string variables?
+
+  StringMultiArrayConstView ds_vars = vars.discrete_string_variables();
+  for (size_t j=0; j<numDiscreteStringVars; ++j, ++cntr)
+    sample_vars[cntr] =
+      (Real) set_value_to_index(ds_vars[j], all_dss_values[j]); // jth row of samples_matrix
+
+  const RealVector& dr_vars = vars.discrete_real_variables();
+  for (size_t j=0; j<numDiscreteRealVars; ++j, ++cntr)
+    sample_vars[cntr] = (Real) dr_vars[j]; // jth row of samples_matrix
+}
+
+
+/** This function and its helpers to follow are needed since NonDSampling
+    supports a richer set of sampling modes than just the active variable
+    subset.  mode_counts() manages the samplingVarsMode setting, while its
+    helper functions (view_{design,aleatory_uncertain,epistemic_uncertain,
+    uncertain,state}_counts) manage the active variables view.  Similar
+    to the computation of starts and counts in creating active variable
+    views, the results of this function are starts and counts for use
+    within model.all_*() set/get functions. */
+void NonDSampling::
+mode_counts(const Model& model, size_t& cv_start,  size_t& num_cv,
+	    size_t& div_start,  size_t& num_div,   size_t& dsv_start,
+	    size_t& num_dsv,    size_t& drv_start, size_t& num_drv) const
+{
+  cv_start = div_start = dsv_start = drv_start = 0;
+  num_cv   = num_div   = num_dsv   = num_drv   = 0;
+  switch (samplingVarsMode) {
+  case ALEATORY_UNCERTAIN:
+    // design vars define starting indices
+    view_design_counts(model, cv_start, div_start, dsv_start, drv_start);
+    // A uncertain vars define counts
+    view_aleatory_uncertain_counts(model, num_cv, num_div, num_dsv, num_drv);
+    break;
+  case ALEATORY_UNCERTAIN_UNIFORM: {
+    // UNIFORM views do not currently support non-relaxed discrete
+    size_t dummy;
+    // continuous design vars define starting indices
+    view_design_counts(model, cv_start, dummy, dummy, dummy);
+    // continuous A uncertain vars define counts
+    view_aleatory_uncertain_counts(model, num_cv, dummy, dummy, dummy);   break;
+  }
+  case EPISTEMIC_UNCERTAIN: {
+    // design + A uncertain vars define starting indices
+    size_t num_cdv,  num_ddiv,  num_ddsv,  num_ddrv,
+           num_cauv, num_dauiv, num_dausv, num_daurv;
+    view_design_counts(model, num_cdv, num_ddiv, num_ddsv, num_ddrv);
+    view_aleatory_uncertain_counts(model, num_cauv, num_dauiv, num_dausv,
+				   num_daurv);
+    cv_start  = num_cdv  + num_cauv;  div_start = num_ddiv + num_dauiv;
+    dsv_start = num_ddsv + num_dausv; drv_start = num_ddrv + num_daurv;
+    // E uncertain vars define counts
+    view_epistemic_uncertain_counts(model, num_cv, num_div, num_dsv, num_drv);
+    break;
+  }
+  case EPISTEMIC_UNCERTAIN_UNIFORM: {
+    // UNIFORM views do not currently support non-relaxed discrete
+    // continuous design + A uncertain vars define starting indices
+    size_t num_cdv, num_cauv, dummy;
+    view_design_counts(model, num_cdv, dummy, dummy, dummy);
+    view_aleatory_uncertain_counts(model, num_cauv, dummy, dummy, dummy);
+    cv_start = num_cdv + num_cauv;
+    // continuous E uncertain vars define counts
+    view_epistemic_uncertain_counts(model, num_cv, dummy, dummy, dummy);  break;
+  }
+  case UNCERTAIN:
+    // design vars define starting indices
+    view_design_counts(model, cv_start, div_start, dsv_start, drv_start);
+    // A+E uncertain vars define counts
+    view_uncertain_counts(model, num_cv, num_div, num_dsv, num_drv);      break;
+  case UNCERTAIN_UNIFORM: {
+    // UNIFORM views do not currently support non-relaxed discrete
+    size_t dummy;
+    // continuous design vars define starting indices
+    view_design_counts(model, cv_start, dummy, dummy, dummy);
+    // continuous A+E uncertain vars define counts
+    view_uncertain_counts(model, num_cv, dummy, dummy, dummy);            break;
+  }
+  case ACTIVE: {
+    const Variables& vars = model.current_variables();
+    cv_start  = vars.cv_start();  num_cv  = vars.cv();
+    div_start = vars.div_start(); num_div = vars.div();
+    dsv_start = vars.dsv_start(); num_dsv = vars.dsv();
+    drv_start = vars.drv_start(); num_drv = vars.drv();                   break;
+  }
+  case ACTIVE_UNIFORM: {
+    // UNIFORM views do not currently support non-relaxed discrete
+    const Variables& vars = model.current_variables();
+    cv_start = vars.cv_start(); num_cv = vars.cv();                       break;
+  }
+  case ALL:
+    num_cv  = model.acv();  num_div = model.adiv();
+    num_dsv = model.adsv(); num_drv = model.adrv();                       break;
+  case ALL_UNIFORM:
+    // UNIFORM views do not currently support non-relaxed discrete
+    num_cv = model.acv();                                                 break;
+  }
+}
+
+
+/** This function computes total design variable counts, not active counts,
+    for use in defining offsets and counts within all variables arrays. */
+void NonDSampling::
+view_design_counts(const Model& model, size_t& num_cdv, size_t& num_ddiv,
+		   size_t& num_ddsv, size_t& num_ddrv) const
+{
+  const Variables& vars = model.current_variables();
+  short active_view = vars.view().first;
+  switch (active_view) {
+  case RELAXED_ALL: case MIXED_ALL: case RELAXED_DESIGN: case MIXED_DESIGN:
+    // design vars are included in active counts from NonD and relaxation
+    // counts have already been applied
+    num_cdv  = numContDesVars;       num_ddiv = numDiscIntDesVars;
+    num_ddsv = numDiscStringDesVars; num_ddrv = numDiscRealDesVars; break;
+  case RELAXED_EPISTEMIC_UNCERTAIN: case RELAXED_STATE:
+  case MIXED_EPISTEMIC_UNCERTAIN: case MIXED_STATE:
+    // design vars are not included in active counts from NonD
+    vars.shared_data().design_counts(num_cdv, num_ddiv, num_ddsv, num_ddrv);
+    break;
+  case RELAXED_UNCERTAIN: case RELAXED_ALEATORY_UNCERTAIN:
+  case   MIXED_UNCERTAIN: case   MIXED_ALEATORY_UNCERTAIN:
+    num_cdv  = vars.cv_start();  num_ddiv = vars.div_start();
+    num_ddsv = vars.dsv_start(); num_ddrv = vars.drv_start(); break;
+  }
+}
+
+
+/** This function computes total aleatory uncertain variable counts,
+    not active counts, for use in defining offsets and counts within
+    all variables arrays. */
+void NonDSampling::
+view_aleatory_uncertain_counts(const Model& model, size_t& num_cauv,
+			       size_t& num_dauiv, size_t& num_dausv,
+			       size_t& num_daurv) const
+{
+  const Variables& vars = model.current_variables();
+  short active_view = vars.view().first;
+  switch (active_view) {
+  case RELAXED_ALL: case RELAXED_UNCERTAIN: case RELAXED_ALEATORY_UNCERTAIN:
+  case   MIXED_ALL: case   MIXED_UNCERTAIN: case   MIXED_ALEATORY_UNCERTAIN:
+    // aleatory vars are included in active counts from NonD and relaxation
+    // counts have already been applied
+    num_cauv  = numContAleatUncVars;       num_dauiv = numDiscIntAleatUncVars;
+    num_dausv = numDiscStringAleatUncVars; num_daurv = numDiscRealAleatUncVars;
+    break;
+  case RELAXED_DESIGN: case RELAXED_STATE: case RELAXED_EPISTEMIC_UNCERTAIN:
+  case MIXED_DESIGN:   case MIXED_STATE:   case MIXED_EPISTEMIC_UNCERTAIN:
+    vars.shared_data().aleatory_uncertain_counts(num_cauv,  num_dauiv,
+						 num_dausv, num_daurv);
+    break;
+  }
+}
+
+
+/** This function computes total epistemic uncertain variable counts,
+    not active counts, for use in defining offsets and counts within
+    all variables arrays. */
+void NonDSampling::
+view_epistemic_uncertain_counts(const Model& model, size_t& num_ceuv,
+				size_t& num_deuiv, size_t& num_deusv,
+				size_t& num_deurv) const
+{
+  const Variables& vars = model.current_variables();
+  short active_view = vars.view().first;
+  switch (active_view) {
+  case RELAXED_ALL: case RELAXED_UNCERTAIN: case RELAXED_EPISTEMIC_UNCERTAIN:
+  case   MIXED_ALL: case   MIXED_UNCERTAIN: case   MIXED_EPISTEMIC_UNCERTAIN:
+    num_ceuv  = numContEpistUncVars;       num_deuiv = numDiscIntEpistUncVars;
+    num_deusv = numDiscStringEpistUncVars; num_deurv = numDiscRealEpistUncVars;
+    break;
+  case RELAXED_DESIGN: case RELAXED_ALEATORY_UNCERTAIN: case RELAXED_STATE:
+  case MIXED_DESIGN:   case MIXED_ALEATORY_UNCERTAIN:   case MIXED_STATE:
+    vars.shared_data().epistemic_uncertain_counts(num_ceuv,  num_deuiv,
+						  num_deusv, num_deurv);
+    break;
+  }
+}
+
+
+/** This function computes total uncertain variable counts, not active counts,
+    for use in defining offsets and counts within all variables arrays. */
+void NonDSampling::
+view_uncertain_counts(const Model& model, size_t& num_cuv, size_t& num_duiv,
+		      size_t& num_dusv, size_t& num_durv) const
+{
+  const Variables& vars = model.current_variables();
+  short active_view = vars.view().first;
+  switch (active_view) {
+  case RELAXED_ALL: case MIXED_ALL: // UNCERTAIN = subset of ACTIVE
+    num_cuv  = numContAleatUncVars       + numContEpistUncVars;
+    num_duiv = numDiscIntAleatUncVars    + numDiscIntEpistUncVars;
+    num_dusv = numDiscStringAleatUncVars + numDiscStringEpistUncVars;
+    num_durv = numDiscRealAleatUncVars   + numDiscRealEpistUncVars;      break;
+  case RELAXED_DESIGN:             case RELAXED_STATE:
+  case RELAXED_ALEATORY_UNCERTAIN: case RELAXED_EPISTEMIC_UNCERTAIN:
+  case MIXED_DESIGN:               case MIXED_STATE:
+  case MIXED_ALEATORY_UNCERTAIN:   case MIXED_EPISTEMIC_UNCERTAIN:
+    vars.shared_data().uncertain_counts(num_cuv, num_duiv, num_dusv, num_durv);
+    break;
+  case RELAXED_UNCERTAIN: case MIXED_UNCERTAIN: // UNCERTAIN = same as ACTIVE
+    num_cuv  = vars.cv();  num_duiv = vars.div();
+    num_dusv = vars.dsv(); num_durv = vars.drv(); break;
+  }
+}
+
+
+void NonDSampling::
+view_state_counts(const Model& model, size_t& num_csv, size_t& num_dsiv,
+		  size_t& num_dssv, size_t& num_dsrv) const
+{
+  const Variables& vars = model.current_variables();
+  short active_view = vars.view().first;
+  switch (active_view) {
+  case RELAXED_ALL: case MIXED_ALL: case RELAXED_STATE: case MIXED_STATE:
+    // state vars are included in active counts from NonD and relaxation
+    // counts have already been applied
+    num_csv  = numContStateVars;       num_dsiv = numDiscIntStateVars;
+    num_dssv = numDiscStringStateVars; num_dsrv = numDiscRealStateVars; break;
+  case RELAXED_ALEATORY_UNCERTAIN: case RELAXED_DESIGN:
+  case   MIXED_ALEATORY_UNCERTAIN: case   MIXED_DESIGN:
+    // state vars are not included in active counts from NonD
+    vars.shared_data().state_counts(num_csv, num_dsiv, num_dssv, num_dsrv);
+    break;
+  case RELAXED_UNCERTAIN: case RELAXED_EPISTEMIC_UNCERTAIN:
+  case   MIXED_UNCERTAIN: case   MIXED_EPISTEMIC_UNCERTAIN:
+    num_csv  = vars.acv()  - vars.cv_start()  - vars.cv();
+    num_dsiv = vars.adiv() - vars.div_start() - vars.div();
+    num_dssv = vars.adsv() - vars.dsv_start() - vars.dsv();
+    num_dsrv = vars.adrv() - vars.drv_start() - vars.drv(); break;
+  }
+}
+
+
+void NonDSampling::initialize_lhs(bool write_message)
+{
+  // keep track of number of LHS executions for this object
+  ++numLHSRuns;
+
+  // Set seed value for input to LHS's random number generator.  Emulate DDACE
+  // behavior in which a user-specified seed gives you repeatable behavior but
+  // no specification gives you random behavior.  A system clock is used to
+  // randomize in the no user specification case.  For cases where
+  // get_parameter_sets() may be called multiple times for the same sampling
+  // iterator (e.g., SBO), support a deterministic sequence of seed values.
+  // This renders the study repeatable but the sampling pattern varies from
+  // one run to the next.
+  if (numLHSRuns == 1) { // set initial seed
+    lhsDriver.rng(rngName);
+    if (!seedSpec) // no user specification --> nonrepeatable behavior
+      randomSeed = generate_system_seed();
+    lhsDriver.seed(randomSeed);
+  }
+  else if (varyPattern) // define sequence of seed values for numLHSRuns > 1
+    lhsDriver.advance_seed_sequence();
+  else // fixed_seed
+    lhsDriver.seed(randomSeed); // reset original/machine-generated seed
+
+  // Needed a way to turn this off when LHS sampling is being used in
+  // NonDAdaptImpSampling because it gets written a _LOT_
+  String sample_string = submethod_enum_to_string(sampleType);
+  if (write_message) {
+    Cout << "\nNonD " << sample_string << " Samples = " << numSamples;
+    if (numLHSRuns == 1 || !varyPattern) {
+      if (seedSpec) Cout << " Seed (user-specified) = ";
+      else          Cout << " Seed (system-generated) = ";
+      Cout << randomSeed << '\n';
+    }
+    else if (rngName == "rnum2") {
+      if (seedSpec) Cout << " Seed (sequence from user-specified) = ";
+      else          Cout << " Seed (sequence from system-generated) = ";
+      Cout << lhsDriver.seed() << '\n';
+    }
+    else // default Boost Mersenne twister
+      Cout << " Seed not reset from previous LHS execution\n";
+  }
+
+  lhsDriver.initialize(sample_string, sampleRanksMode, !subIteratorFlag);
+}
+
+
+void NonDSampling::
+compute_statistics(const RealMatrix&     vars_samples,
+		   const IntResponseMap& resp_samples)
+{
+  StringMultiArrayConstView
+    acv_labels  = iteratedModel.all_continuous_variable_labels(),
+    adiv_labels = iteratedModel.all_discrete_int_variable_labels(),
+    adsv_labels = iteratedModel.all_discrete_string_variable_labels(),
+    adrv_labels = iteratedModel.all_discrete_real_variable_labels();
+  size_t cv_start, num_cv, div_start, num_div, dsv_start, num_dsv,
+    drv_start, num_drv;
+  mode_counts(iteratedModel, cv_start, num_cv, div_start, num_div,
+	      dsv_start, num_dsv, drv_start, num_drv);
+  StringMultiArrayConstView
+    cv_labels  =
+      acv_labels[boost::indices[idx_range(cv_start, cv_start+num_cv)]],
+    div_labels =
+      adiv_labels[boost::indices[idx_range(div_start, div_start+num_div)]],
+    dsv_labels =
+      adsv_labels[boost::indices[idx_range(dsv_start, dsv_start+num_dsv)]],
+    drv_labels =
+      adrv_labels[boost::indices[idx_range(drv_start, drv_start+num_drv)]];
+
+  // archive the active variables with the results
+  if (resultsDB.active()) {
+    if (num_cv)
+      resultsDB.insert(run_identifier(), resultsNames.cv_labels, cv_labels);
+    if (num_div)
+      resultsDB.insert(run_identifier(), resultsNames.div_labels, div_labels);
+    if (num_dsv)
+      resultsDB.insert(run_identifier(), resultsNames.dsv_labels, dsv_labels);
+    if (num_drv)
+      resultsDB.insert(run_identifier(), resultsNames.drv_labels, drv_labels);
+    resultsDB.insert(run_identifier(), resultsNames.fn_labels,
+		     iteratedModel.response_labels());
+  }
+
+  if (epistemicStats) // Epistemic/mixed
+    compute_intervals(resp_samples); // compute min/max response intervals
+  else { // Aleatory
+    // compute means and std deviations with confidence intervals
+    compute_moments(resp_samples);
+    // compute CDF/CCDF mappings of z to p/beta and p/beta to z
+    if (totalLevelRequests)
+      compute_distribution_mappings(resp_samples);
+  }
+
+  // Don't compute for now: too expensive
+  // if (!subIteratorFlag) {
+  //   nonDSampCorr.compute_correlations(vars_samples, resp_samples);
+  //   // archive the correlations to the results DB
+  //   nonDSampCorr.archive_correlations(run_identifier(), resultsDB, cv_labels,
+		// 		      div_labels, dsv_labels, drv_labels,
+		// 		      iteratedModel.response_labels());
+  // }
+  if (!finalStatistics.is_null())
+    update_final_statistics();
+}
+
+
+void NonDSampling::compute_intervals(const IntResponseMap& samples)
+{
+  // For the samples array, calculate min/max response intervals
+
+  using boost::math::isfinite;
+  size_t i, j, num_obs = samples.size(), num_samp;
+  const StringArray& resp_labels = iteratedModel.response_labels();
+
+  if (extremeValues.empty()) extremeValues.shapeUninitialized(2, numFunctions);
+  IntRespMCIter it;
+  for (i=0; i<numFunctions; ++i) {
+    num_samp = 0;
+    Real min = DBL_MAX, max = -DBL_MAX;
+    for (it=samples.begin(); it!=samples.end(); ++it) {
+      const Real& sample = it->second.function_value(i);
+      if (isfinite(sample)) { // neither NaN nor +/-Inf
+	if (sample < min) min = sample;
+	if (sample > max) max = sample;
+	++num_samp;
+      }
+    }
+    extremeValues(0, i) = min;
+    extremeValues(1, i) = max;
+    if (num_samp != num_obs)
+      Cerr << "Warning: sampling statistics for " << resp_labels[i] << " omit "
+	   << num_obs-num_samp << " failed evaluations out of " << num_obs
+	   << " samples.\n";
+  }
+
+  if (resultsDB.active()) {
+    MetaDataType md;
+    md["Row Labels"] = make_metadatavalue("Min", "Max");
+    md["Column Labels"] = make_metadatavalue(resp_labels);
+    resultsDB.insert(run_identifier(), resultsNames.extreme_values,
+		     extremeValues, md);
+  }
+}
+
+
+void NonDSampling::compute_moments(const IntResponseMap& samples)
+{
+  // For the samples array, calculate means and standard deviations
+  // with confidence intervals
+
+  using boost::math::isfinite;
+  size_t i, j, num_obs = samples.size(), num_samp;
+  Real sum, var, skew, kurt;
+  const StringArray& resp_labels = iteratedModel.response_labels();
+
+  if (momentStats.empty()) momentStats.shapeUninitialized(4, numFunctions);
+  if (momentCIs.empty()) momentCIs.shapeUninitialized(4, numFunctions);
+
+  IntRespMCIter it;
+  for (i=0; i<numFunctions; ++i) {
+
+    num_samp  = 0;
+    sum = var = skew = kurt = 0.;
+    // means
+    for (it=samples.begin(); it!=samples.end(); ++it) {
+      const Real& sample = it->second.function_value(i);
+      if (isfinite(sample)) { // neither NaN nor +/-Inf
+	sum += sample;
+	++num_samp;
+      }
+    }
+
+    if (num_samp != num_obs)
+      Cerr << "Warning: sampling statistics for " << resp_labels[i] << " omit "
+	   << num_obs-num_samp << " failed evaluations out of " << num_obs
+	   << " samples.\n";
+    if (!num_samp) {
+      Cerr << "Error: Number of samples for " << resp_labels[i]
+	   << " must be nonzero for moment calculation in NonDSampling::"
+	   << "compute_statistics()." << std::endl;
+      abort_handler(-1);
+    }
+
+    Real* moments_i = momentStats[i];
+    Real& mean = moments_i[0];
+    mean = sum/((Real)num_samp);
+
+    // accumulate variance, skewness, and kurtosis
+    Real centered_fn, pow_fn;
+    for (it=samples.begin(); it!=samples.end(); ++it) {
+      const Real& sample = it->second.function_value(i);
+      if (isfinite(sample)) { // neither NaN nor +/-Inf
+	pow_fn  = centered_fn = sample - mean;
+	pow_fn *= centered_fn; var  += pow_fn;
+	pow_fn *= centered_fn; skew += pow_fn;
+	pow_fn *= centered_fn; kurt += pow_fn;
+      }
+    }
+
+    // sample std deviation
+    Real& std_dev = moments_i[1];
+    std_dev = (num_samp > 1) ? std::sqrt(var/(Real)(num_samp-1)) : 0.;
+
+    // skewness
+    moments_i[2] = (num_samp > 2 && var > 0.) ?
+      // sample skewness
+      skew/(Real)num_samp/std::pow(var/(Real)num_samp,1.5) *
+      // population skewness
+      std::sqrt((Real)(num_samp*(num_samp-1)))/(Real)(num_samp-2) :
+      // for no variation, central moment is zero
+      0.;
+
+    // kurtosis
+    moments_i[3] = (num_samp > 3 && var > 0.) ?
+      // sample kurtosis
+      (Real)((num_samp+1)*num_samp*(num_samp-1))*kurt/
+      (Real)((num_samp-2)*(num_samp-3)*var*var) -
+      // population kurtosis
+      3.*std::pow((Real)(num_samp-1),2)/(Real)((num_samp-2)*(num_samp-3)) :
+      // for no variation, central moment is zero minus excess kurtosis
+      -3.;
+
+    if (num_samp > 1) {
+      // 95% confidence intervals (2-sided interval, not 1-sided limit)
+      Real dof = num_samp - 1;
+//#ifdef HAVE_BOOST
+      // mean: the better formula does not assume known variance but requires
+      // a function for the Student's t-distr. with (num_samp-1) degrees of
+      // freedom (Haldar & Mahadevan, p. 127).
+      Pecos::students_t_dist t_dist(dof);
+      Real mean_ci_delta =
+	std_dev*bmth::quantile(t_dist,0.975)/std::sqrt((Real)num_samp);
+      momentCIs(0,i) = mean - mean_ci_delta;
+      momentCIs(1,i) = mean + mean_ci_delta;
+      // std dev: chi-square distribution with (num_samp-1) degrees of freedom
+      // (Haldar & Mahadevan, p. 132).
+      Pecos::chi_squared_dist chisq(dof);
+      momentCIs(2,i) = std_dev*std::sqrt(dof/bmth::quantile(chisq, 0.975));
+      momentCIs(3,i) = std_dev*std::sqrt(dof/bmth::quantile(chisq, 0.025));
+/*
+#elif HAVE_GSL
+      // mean: the better formula does not assume known variance but requires
+      // a function for the Student's t-distr. with (num_samp-1) degrees of
+      // freedom (Haldar & Mahadevan, p. 127).
+      mean95CIDeltas[i]
+	= std_dev*gsl_cdf_tdist_Pinv(0.975,dof)/std::sqrt((Real)num_samp);
+      // std dev: chi-square distribution with (num_samp-1) degrees of freedom
+      // (Haldar & Mahadevan, p. 132).
+      stdDev95CILowerBnds[i]
+        = std_dev*std::sqrt(dof/gsl_cdf_chisq_Pinv(0.975, dof));
+      stdDev95CIUpperBnds[i]
+        = std_dev*std::sqrt(dof/gsl_cdf_chisq_Pinv(0.025, dof));
+#else
+      // mean: k_(alpha/2) = Phi^(-1)(0.975) = 1.96 (Haldar & Mahadevan,
+      // p. 123).  This simple formula assumes a known variance, which
+      // requires a sample of sufficient size (i.e., greater than 10).
+      mean95CIDeltas[i] = 1.96*std_dev/std::sqrt((Real)num_samp);
+#endif // HAVE_BOOST
+*/
+    }
+    else
+      momentCIs(0,i) = momentCIs(1,i) = momentCIs(2,i) = momentCIs(3,i) = 0.0;
+  }
+
+  if (resultsDB.active()) {
+    // archive the moments to results DB
+    MetaDataType md_moments;
+    md_moments["Row Labels"] =
+      make_metadatavalue("Mean", "Standard Deviation", "Skewness", "Kurtosis");
+    md_moments["Column Labels"] = make_metadatavalue(resp_labels);
+    resultsDB.insert(run_identifier(), resultsNames.moments_std,
+		     momentStats, md_moments);
+    // archive the confidence intervals to results DB
+    MetaDataType md;
+    md["Row Labels"] =
+      make_metadatavalue("LowerCI_Mean", "UpperCI_Mean", "LowerCI_StdDev",
+			 "UpperCI_StdDev");
+    md["Column Labels"] = make_metadatavalue(resp_labels);
+    resultsDB.insert(run_identifier(), resultsNames.moment_cis, momentCIs, md);
+  }
+}
+
+
+void NonDSampling::compute_distribution_mappings(const IntResponseMap& samples)
+{
+  // Size the output arrays here instead of in the ctor in order to support
+  // alternate sampling ctors.
+  initialize_distribution_mappings();
+  archive_allocate_mappings();
+  if (pdfOutput) {
+    computedPDFAbscissas.resize(numFunctions);
+    computedPDFOrdinates.resize(numFunctions);
+    archive_allocate_pdf();
+  }
+
+  // For the samples array, calculate the following statistics:
+  // > CDF/CCDF mappings of response levels to probability/reliability levels
+  // > CDF/CCDF mappings of probability/reliability levels to response levels
+  using boost::math::isfinite;
+  size_t i, j, k, num_obs = samples.size(), num_samp, bin_accumulator;
+  const StringArray& resp_labels = iteratedModel.response_labels();
+  RealArray sorted_samples; // STL-based array for sorting
+  SizetArray bins; Real min, max;
+
+  // check if moments are required, and if so, compute them now
+  if (momentStats.empty()) {
+    bool need_moments = false;
+    for (i=0; i<numFunctions; ++i)
+      if ( !requestedRelLevels[i].empty() ||
+	   ( !requestedRespLevels[i].empty() &&
+	     respLevelTarget == RELIABILITIES ) )
+	{ need_moments = true; break; }
+    if (need_moments) {
+      Cerr << "Error: required moments not available in compute_distribution_"
+	   << "mappings().  Call compute_moments() first." << std::endl;
+      abort_handler(-1);
+      // Issue with the following approach is that subsequent invocations of
+      // compute_distribution_mappings() without compute_moments() would not
+      // be detected and old moments would be used.  Performing more rigorous
+      // bookkeeping of moment updates is overkill for current use cases.
+      //Cerr << "Warning: moments not available in compute_distribution_"
+      //     << "mappings(); computing them now." << std::endl;
+      //compute_moments(samples);
+    }
+  }
+
+  IntRespMCIter it;
+  for (i=0; i<numFunctions; ++i) {
+
+    // CDF/CCDF mappings: z -> p/beta/beta* and p/beta/beta* -> z
+    size_t rl_len = requestedRespLevels[i].length(),
+           pl_len = requestedProbLevels[i].length(),
+           bl_len = requestedRelLevels[i].length(),
+           gl_len = requestedGenRelLevels[i].length();
+
+    // ----------------------------------------------------------------------
+    // Preliminaries: define finite subset, sort (if needed), and bin samples
+    // ----------------------------------------------------------------------
+    num_samp = 0;
+    if (pl_len || gl_len) { // sort samples array for p/beta* -> z mappings
+      sorted_samples.clear(); sorted_samples.reserve(num_obs);
+      for (it=samples.begin(); it!=samples.end(); ++it) {
+	const Real& sample = it->second.function_value(i);
+	if (isfinite(sample))
+	  { ++num_samp; sorted_samples.push_back(sample); }
+      }
+      // sort in ascending order
+      std::sort(sorted_samples.begin(), sorted_samples.end());
+      if (pdfOutput)
+	{ min = sorted_samples[0]; max = sorted_samples[num_samp-1]; }
+      // in case of rl_len mixed with pl_len/gl_len, bin using sorted array.
+      // Note: all bins open on right end due to use of less than.
+      if (rl_len && respLevelTarget != RELIABILITIES) {
+	const RealVector& req_rl_i = requestedRespLevels[i];
+        bins.assign(rl_len+1, 0); size_t samp_cntr = 0;
+	for (j=0; j<rl_len; ++j)
+	  while (samp_cntr<num_samp && sorted_samples[samp_cntr]<req_rl_i[j])
+	    { ++bins[j]; ++samp_cntr; }
+	if (num_samp > samp_cntr)
+	  bins[rl_len] += num_samp - samp_cntr;
+      }
+    }
+    else if (rl_len && respLevelTarget != RELIABILITIES) {
+      // in case of rl_len without pl_len/gl_len, bin from original sample set
+      const RealVector& req_rl_i = requestedRespLevels[i];
+      bins.assign(rl_len+1, 0); min = DBL_MAX; max = -DBL_MAX;
+      for (it=samples.begin(); it!=samples.end(); ++it) {
+	const Real& sample = it->second.function_value(i);
+	if (isfinite(sample)) {
+	  ++num_samp;
+	  if (pdfOutput) {
+	    if (sample < min) min = sample;
+	    if (sample > max) max = sample;
+	  }
+	  // 1st PDF bin from -inf to 1st resp lev; last PDF bin from last resp
+	  // lev to +inf. Note: all bins open on right end due to use of <.
+	  bool found = false;
+	  for (k=0; k<rl_len; ++k)
+	    if (sample < req_rl_i[k])
+	      { ++bins[k]; found = true; break; }
+	  if (!found)
+	    ++bins[rl_len];
+	}
+      }
+    }
+
+    // ----------------
+    // Process mappings
+    // ----------------
+    if (rl_len) {
+      switch (respLevelTarget) {
+      case PROBABILITIES: case GEN_RELIABILITIES: {
+	// z -> p/beta* (based on binning)
+	bin_accumulator = 0;
+	for (j=0; j<rl_len; ++j) { // compute CDF/CCDF p/beta*
+	  bin_accumulator += bins[j];
+	  Real cdf_prob = (Real)bin_accumulator/(Real)num_samp;
+	  Real computed_prob = (cdfFlag) ? cdf_prob : 1. - cdf_prob;
+	  if (respLevelTarget == PROBABILITIES)
+	    computedProbLevels[i][j]   =  computed_prob;
+	  else
+	    computedGenRelLevels[i][j] = -Pecos::Phi_inverse(computed_prob);
+	}
+	break;
+      }
+      case RELIABILITIES: { // z -> beta (based on moment projection)
+	Real& mean = momentStats(0,i); Real& std_dev = momentStats(1,i);
+	for (j=0; j<rl_len; j++) {
+	  const Real& z = requestedRespLevels[i][j];
+	  if (std_dev > Pecos::SMALL_NUMBER) {
+	    Real ratio = (mean - z)/std_dev;
+	    computedRelLevels[i][j] = (cdfFlag) ? ratio : -ratio;
+	  }
+	  else
+	    computedRelLevels[i][j]
+	      = ( (cdfFlag && mean <= z) || (!cdfFlag && mean > z) )
+	      ? -Pecos::LARGE_NUMBER : Pecos::LARGE_NUMBER;
+	}
+	break;
+      }
+      }
+    }
+    for (j=0; j<pl_len+gl_len; j++) { // p/beta* -> z
+      Real p = (j<pl_len) ? requestedProbLevels[i][j] :
+	Pecos::Phi(-requestedGenRelLevels[i][j-pl_len]);
+      // since each sample has 1/N probability, a probability level can be
+      // directly converted to an index within a sorted array (index =~ p * N)
+      Real cdf_p_x_obs = (cdfFlag) ? p*(Real)num_samp : (1.-p)*(Real)num_samp;
+      // convert to an int and round down using std::floor().  Apply a small
+      // numerical adjustment so that probabilities on the boundaries
+      // (common with round probabilities and factor of 10 samples)
+      // are consistently rounded down (consistent with CDF p(g<=z)).
+      Real order = (cdf_p_x_obs > .9)
+	         ? std::pow(10., ceil(std::log10(cdf_p_x_obs))) : 0.;
+      int index = (int)std::floor(cdf_p_x_obs - order*DBL_EPSILON);
+      // clip at array ends due to possible roundoff effects
+      if (index < 0)         index = 0;
+      if (index >= num_samp) index = num_samp - 1;
+      if (j<pl_len)
+	computedRespLevels[i][j] = sorted_samples[index];
+      else
+	computedRespLevels[i][j+bl_len] = sorted_samples[index];
+    }
+    if (bl_len) {
+      Real& mean = momentStats(0,i); Real& std_dev = momentStats(1,i);
+      for (j=0; j<bl_len; j++) { // beta -> z
+	const Real& beta = requestedRelLevels[i][j];
+	computedRespLevels[i][j+pl_len] = (cdfFlag) ?
+	  mean - beta * std_dev : mean + beta * std_dev;
+      }
+    }
+
+    // archive the mappings from response levels
+    archive_from_resp(i);
+    // archive the mappings to response levels
+    archive_to_resp(i);
+
+    // ---------------------------------------------------------------------
+    // Post-process for PDF incorporating all requested/computed resp levels
+    // ---------------------------------------------------------------------
+    if (pdfOutput) {
+      size_t req_comp_rl_len = pl_len + gl_len;
+      if (respLevelTarget != RELIABILITIES) req_comp_rl_len += rl_len;
+      if (req_comp_rl_len) {
+	RealVector pdf_all_rlevs;
+	if (pl_len || gl_len) {
+	  // merge all requested & computed rlevs into pdf rlevs and sort
+	  pdf_all_rlevs.sizeUninitialized(req_comp_rl_len);
+	  // merge requested/computed --> pdf_all_rlevs
+	  int offset = 0;
+	  if (rl_len && respLevelTarget != RELIABILITIES) {
+	    copy_data_partial(requestedRespLevels[i], pdf_all_rlevs, 0);
+	    offset += rl_len;
+	  }
+	  if (pl_len) {
+	    copy_data_partial(computedRespLevels[i], 0, (int)pl_len,
+			      pdf_all_rlevs, offset);
+	    offset += pl_len;
+	  }
+	  if (gl_len)
+	    copy_data_partial(computedRespLevels[i], (int)(pl_len+bl_len),
+			      (int)gl_len, pdf_all_rlevs, offset);
+	  // sort combined array; retain unique entries; update req_comp_rl_len
+	  Real* start = pdf_all_rlevs.values();
+	  std::sort(start, start+req_comp_rl_len);
+	  req_comp_rl_len = std::distance(start,
+	    std::unique(start, start+req_comp_rl_len));
+	  // (re)compute bins from sorted_samples.  Note that these bins are
+	  // open on right end due to use of strictly less than.
+	  bins.assign(req_comp_rl_len+1, 0); size_t samp_cntr = 0;
+	  for (j=0; j<req_comp_rl_len; ++j)
+	    while (samp_cntr < num_samp &&
+		   sorted_samples[samp_cntr] < pdf_all_rlevs[j])
+	      { ++bins[j]; ++samp_cntr; }
+	  if (num_samp > samp_cntr)
+	    bins[req_comp_rl_len] += num_samp - samp_cntr;
+	}
+	RealVector& pdf_rlevs = (pl_len || gl_len) ?
+	  pdf_all_rlevs : requestedRespLevels[i];
+	size_t last_rl_index = req_comp_rl_len-1;
+	const Real& lev_0    = pdf_rlevs[0];
+	const Real& lev_last = pdf_rlevs[last_rl_index];
+	// to properly sum to 1, final PDF bin must be closed on right end.
+	// --> where the max sample value defines the last response level,
+	//     move any max samples on right boundary inside last PDF bin.
+	if (max <= lev_last && bins[req_comp_rl_len]) {
+	  bins[req_comp_rl_len-1] += bins[req_comp_rl_len];
+	  bins[req_comp_rl_len]    = 0;
+	}
+
+	// compute computedPDF{Abscissas,Ordinates} from bin counts and widths
+	size_t pdf_size = last_rl_index;
+	if (min < lev_0)    ++pdf_size;
+	if (max > lev_last) ++pdf_size;
+	RealVector& abs_i = computedPDFAbscissas[i]; abs_i.resize(pdf_size+1);
+	RealVector& ord_i = computedPDFOrdinates[i]; ord_i.resize(pdf_size);
+	size_t offset = 0;
+	if (min < lev_0) {
+	  abs_i[0] = min;
+	  ord_i[0] = (Real)bins[0]/(Real)num_samp/(lev_0 - min);
+	  offset = 1;
+	}
+	for (j=0; j<last_rl_index; ++j) {
+	  abs_i[j+offset] = pdf_rlevs[j];
+	  ord_i[j+offset]
+	    = (Real)bins[j+1]/(Real)num_samp/(pdf_rlevs[j+1] - pdf_rlevs[j]);
+	}
+	if (max > lev_last) {
+	  abs_i[pdf_size-1] = pdf_rlevs[last_rl_index];
+	  abs_i[pdf_size]   = max;
+	  ord_i[pdf_size-1]
+	    = (Real)bins[req_comp_rl_len]/(Real)num_samp/(max - lev_last);
+	}
+	else
+	  abs_i[pdf_size] = pdf_rlevs[last_rl_index];
+      }
+      archive_pdf(i);
+    }
+  }
+}
+
+
+void NonDSampling::update_final_statistics()
+{
+  //if (finalStatistics.is_null())
+  //  initialize_final_statistics();
+
+  if (epistemicStats) {
+    size_t i, cntr = 0;
+    for (i=0; i<numFunctions; ++i) {
+      finalStatistics.function_value(extremeValues(0, i), cntr++);
+      finalStatistics.function_value(extremeValues(1, i), cntr++);
+    }
+  }
+  else // moments + level mappings
+    NonD::update_final_statistics();
+}
+
+
+void NonDSampling::print_statistics(std::ostream& s) const
+{
+  if (epistemicStats) // output only min & max values in the epistemic case
+    print_intervals(s);
+  else {
+    print_moments(s);
+    if (totalLevelRequests) {
+      print_distribution_mappings(s);
+      if (pdfOutput)
+	print_pdf_mappings(s);
+      print_system_mappings(s);
+    }
+  }
+  if (!subIteratorFlag) {
+    StringMultiArrayConstView
+      acv_labels  = iteratedModel.all_continuous_variable_labels(),
+      adiv_labels = iteratedModel.all_discrete_int_variable_labels(),
+      adsv_labels = iteratedModel.all_discrete_string_variable_labels(),
+      adrv_labels = iteratedModel.all_discrete_real_variable_labels();
+    size_t cv_start, num_cv, div_start, num_div, dsv_start, num_dsv,
+      drv_start, num_drv;
+    mode_counts(iteratedModel, cv_start, num_cv, div_start, num_div,
+		dsv_start, num_dsv, drv_start, num_drv);
+    StringMultiArrayConstView
+      cv_labels  =
+        acv_labels[boost::indices[idx_range(cv_start, cv_start+num_cv)]],
+      div_labels =
+        adiv_labels[boost::indices[idx_range(div_start, div_start+num_div)]],
+      dsv_labels =
+        adsv_labels[boost::indices[idx_range(dsv_start, dsv_start+num_dsv)]],
+      drv_labels =
+        adrv_labels[boost::indices[idx_range(drv_start, drv_start+num_drv)]];
+    // Don't output for now
+    // nonDSampCorr.print_correlations(s, cv_labels, div_labels, dsv_labels,
+				//     drv_labels,iteratedModel.response_labels());
+  }
+}
+
+
+void NonDSampling::print_intervals(std::ostream& s) const
+{
+  const StringArray& resp_labels = iteratedModel.response_labels();
+
+  s << std::scientific << std::setprecision(write_precision)
+    << "\nMin and Max values for each response function:\n";
+  for (size_t i=0; i<numFunctions; ++i)
+    s << resp_labels[i] << ":  Min = " << extremeValues(0, i)
+      << "  Max = " << extremeValues(1, i) << '\n';
+}
+
+
+void NonDSampling::print_moments(std::ostream& s) const
+{
+  const StringArray& resp_labels = iteratedModel.response_labels();
+
+  s << std::scientific << std::setprecision(write_precision);
+
+  size_t i, j, width = write_precision+7;
+
+  s << "\nMoment-based statistics for each response function:\n"
+    << std::setw(width+15) << "Mean"     << std::setw(width+1) << "Std Dev"
+    << std::setw(width+1)  << "Skewness" << std::setw(width+2) << "Kurtosis\n";
+  //<< std::setw(width+2)  << "Coeff of Var\n";
+  for (i=0; i<numFunctions; ++i) {
+    const Real* moments_i = momentStats[i];
+    s << std::setw(14) << resp_labels[i];
+    for (j=0; j<4; ++j)
+      s << ' ' << std::setw(width) << moments_i[j];
+    s << '\n';
+  }
+  if (numSamples > 1) {
+    // output 95% confidence intervals as (,) interval
+    s << "\n95% confidence intervals for each response function:\n"
+      << std::setw(width+15) << "LowerCI_Mean" << std::setw(width+1)
+      << "UpperCI_Mean" << std::setw(width+1)  << "LowerCI_StdDev"
+      << std::setw(width+2) << "UpperCI_StdDev\n";
+    for (i=0; i<numFunctions; ++i)
+      s << std::setw(14) << resp_labels[i]
+	<< ' ' << std::setw(width) << momentCIs(0, i)
+	<< ' ' << std::setw(width) << momentCIs(1, i)
+	<< ' ' << std::setw(width) << momentCIs(2, i)
+	<< ' ' << std::setw(width) << momentCIs(3, i) << '\n';
+  }
+}
+
+
+void NonDSampling::print_pdf_mappings(std::ostream& s) const
+{
+  const StringArray& resp_labels = iteratedModel.response_labels();
+
+  // output CDF/CCDF probabilities resulting from binning or CDF/CCDF
+  // reliabilities resulting from number of std devs separating mean & target
+  s << std::scientific << std::setprecision(write_precision)
+    << "\nProbability Density Function (PDF) histograms for each response "
+    << "function:\n";
+  size_t i, j, width = write_precision+7;
+  for (i=0; i<numFunctions; ++i) {
+    if (!requestedRespLevels[i].empty() || !computedRespLevels[i].empty()) {
+      s << "PDF for " << resp_labels[i] << ":\n"
+	<< "          Bin Lower          Bin Upper      Density Value\n"
+	<< "          ---------          ---------      -------------\n";
+
+      size_t pdf_len = computedPDFOrdinates[i].length();
+      for (j=0; j<pdf_len; ++j)
+	s << "  " << std::setw(width) << computedPDFAbscissas[i][j] << "  "
+	  << std::setw(width) << computedPDFAbscissas[i][j+1] << "  "
+	  << std::setw(width) << computedPDFOrdinates[i][j] << '\n';
+    }
+  }
+}
+
+
+void NonDSampling::archive_allocate_pdf() // const
+{
+  if (!resultsDB.active())  return;
+
+  // pdf per function, possibly empty
+  MetaDataType md;
+  md["Array Spans"] = make_metadatavalue("Response Functions");
+  md["Row Labels"] =
+    make_metadatavalue("Bin Lower", "Bin Upper", "Density Value");
+  resultsDB.array_allocate<RealMatrix>
+    (run_identifier(), resultsNames.pdf_histograms, numFunctions, md);
+}
+
+
+void NonDSampling::archive_pdf(size_t i) // const
+{
+  if (!resultsDB.active()) return;
+
+  size_t pdf_len = computedPDFOrdinates[i].length();
+  RealMatrix pdf(3, pdf_len);
+  for (size_t j=0; j<pdf_len; ++j) {
+    pdf(0, j) = computedPDFAbscissas[i][j];
+    pdf(1, j) = computedPDFAbscissas[i][j+1];
+    pdf(2, j) = computedPDFOrdinates[i][j];
+  }
+
+  resultsDB.array_insert<RealMatrix>
+    (run_identifier(), resultsNames.pdf_histograms, i, pdf);
+}
+
+} // namespace Dakota
+
Index: /issm/trunk-jpl/externalpackages/dakota/install-6.2-linux-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/install-6.2-linux-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/install-6.2-linux-static.sh	(revision 24593)
@@ -0,0 +1,76 @@
+#!/bin/bash
+set -eu
+
+
+# Constants
+#
+DAK_ROOT=${ISSM_DIR}/externalpackages/dakota
+MPI_INSTALL=${ISSM_DIR}/externalpackages/mpich/install
+VER="6.2"
+
+## Environment
+#
+export BLAS_LIBS="-L${ISSM_DIR}/externalpackages/lapack/install/lib -lblas -L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" # Need to export BLAS_LIBS *and* pass it as an option to CMake to ensure that external packages also find it
+export BOOST_ROOT=${ISSM_DIR}/externalpackages/boost/install
+export CXXFLAGS='-std=c++98' # Setting CXXFLAGS to deal with C++11 incompatibility with Matlab's Boost (absolutely necessary for this version)
+#export CXXFLAGS='-std=c++11'
+export DAK_BUILD=${DAK_ROOT}/build
+export DAK_INSTALL=${DAK_ROOT}/install
+export DAK_SRC=${DAK_ROOT}/src
+export LAPACK_LIBS="-L${ISSM_DIR}/externalpackages/lapack/install/lib -llapack -L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" # Need to export LAPACK_LIBS *and* pass it as an option to CMake to ensure that external packages also find it
+export MPIHOME=${MPI_INSTALL} # This appears to only be used by certain external packages and examples
+
+# Cleanup
+rm -rf build install src
+mkdir build install src
+
+#Download from ISSM server
+${ISSM_DIR}/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/dakota-${VER}-public.src.tar.gz" "dakota-${VER}-public-src.tar.gz"
+
+# Unpack source
+tar -zxvf dakota-${VER}-public-src.tar.gz
+
+# Move source to 'src' directory
+mv dakota-${VER}.0.src/* src
+rm -rf dakota-${VER}.0.src
+
+# Copy customized source and configuration files to 'src' driectory
+cp configs/${VER}/linux/cmake/BuildDakotaCustom.cmake ${DAK_SRC}/cmake
+cp configs/${VER}/linux/cmake/DakotaDev.cmake ${DAK_SRC}/cmake
+cp configs/${VER}/linux/packages/DDACE/src/Analyzer/MainEffectsExcelOutput.cpp ${DAK_SRC}/packages/DDACE/src/Analyzer
+cp configs/${VER}/linux/packages/surfpack/src/surfaces/nkm/NKM_KrigingModel.cpp ${DAK_SRC}/packages/surfpack/src/surfaces/nkm
+cp configs/${VER}/linux/src/DakotaInterface.cpp ${DAK_SRC}/src
+cp configs/${VER}/linux/src/NonDLocalReliability.cpp ${DAK_SRC}/src
+cp configs/${VER}/linux/src/NonDSampling.cpp ${DAK_SRC}/src
+
+# Configure
+cd ${DAK_BUILD}
+cmake \
+	-DBUILD_SHARED_LIBS=OFF \
+	-DBUILD_STATIC_LIBS=ON \
+	-DCMAKE_C_COMPILER=${MPI_INSTALL}/bin/mpicc \
+	-DCMAKE_CXX_COMPILER=${MPI_INSTALL}/bin/mpicxx \
+	-DCMAKE_Fortran_COMPILER=${MPI_INSTALL}/bin/mpif77 \
+	-DCMAKE_C_FLAGS="-fPIC" \
+	-DCMAKE_CXX_FLAGS="-fPIC" \
+	-DCMAKE_Fortran_FLAGS="-fPIC" \
+	-DHAVE_ACRO=OFF \
+	-DHAVE_JEGA=OFF \
+	-C${DAK_SRC}/cmake/BuildDakotaCustom.cmake \
+	-C${DAK_SRC}/cmake/DakotaDev.cmake \
+	${DAK_SRC}
+
+# Compile and install
+if [ $# -eq 0 ]; then
+	make
+	make install
+else
+	make -j $1
+	make -j $1 install
+fi
+
+cd ${DAK_INSTALL}
+
+# Comment out definition of HAVE_MPI in Teuchos config header file in order to
+# avoid conflict with our definition
+sed -i -e "s/#define HAVE_MPI/\/* #define HAVE_MPI *\//g" include/Teuchos_config.h
Index: /issm/trunk-jpl/externalpackages/dakota/install-6.2-linux.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/dakota/install-6.2-linux.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/dakota/install-6.2-linux.sh	(revision 24593)
@@ -0,0 +1,73 @@
+#!/bin/bash
+set -eu
+
+
+# Constants
+#
+DAK_ROOT=${ISSM_DIR}/externalpackages/dakota
+MPI_INSTALL=${ISSM_DIR}/externalpackages/mpich/install
+VER="6.2"
+
+## Environment
+#
+export BLAS_LIBS="-L${ISSM_DIR}/externalpackages/lapack/install/lib -lblas" # Need to export BLAS_LIBS *and* pass it as an option to CMake to ensure that external packages also find it
+export BOOST_ROOT=${ISSM_DIR}/externalpackages/boost/install
+export CXXFLAGS='-std=c++98' # Setting CXXFLAGS to deal with C++11 incompatibility with Matlab's Boost (absolutely necessary for this version)
+#export CXXFLAGS='-std=c++11'
+export DAK_BUILD=${DAK_ROOT}/build
+export DAK_INSTALL=${DAK_ROOT}/install
+export DAK_SRC=${DAK_ROOT}/src
+export LAPACK_LIBS="-L${ISSM_DIR}/externalpackages/lapack/install/lib -llapack" # Need to export LAPACK_LIBS *and* pass it as an option to CMake to ensure that external packages also find it
+export MPIHOME=${MPI_INSTALL} # This appears to only be used by certain external packages and examples
+
+# Cleanup
+rm -rf build install src
+mkdir build install src
+
+#Download from ISSM server
+${ISSM_DIR}/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/dakota-${VER}-public.src.tar.gz" "dakota-${VER}-public-src.tar.gz"
+
+# Unpack source
+tar -zxvf dakota-${VER}-public-src.tar.gz
+
+# Move source to 'src' directory
+mv dakota-${VER}.0.src/* src
+rm -rf dakota-${VER}.0.src
+
+# Copy customized source and configuration files to 'src' driectory
+cp configs/${VER}/linux/cmake/BuildDakotaCustom.cmake ${DAK_SRC}/cmake
+cp configs/${VER}/linux/cmake/DakotaDev.cmake ${DAK_SRC}/cmake
+cp configs/${VER}/linux/packages/DDACE/src/Analyzer/MainEffectsExcelOutput.cpp ${DAK_SRC}/packages/DDACE/src/Analyzer
+cp configs/${VER}/linux/packages/surfpack/src/surfaces/nkm/NKM_KrigingModel.cpp ${DAK_SRC}/packages/surfpack/src/surfaces/nkm
+cp configs/${VER}/linux/src/DakotaInterface.cpp ${DAK_SRC}/src
+cp configs/${VER}/linux/src/NonDLocalReliability.cpp ${DAK_SRC}/src
+cp configs/${VER}/linux/src/NonDSampling.cpp ${DAK_SRC}/src
+
+# Configure
+cd ${DAK_BUILD}
+cmake \
+	-DBUILD_SHARED_LIBS=ON \
+	-DBUILD_STATIC_LIBS=OFF \
+	-DCMAKE_C_COMPILER=${MPI_INSTALL}/bin/mpicc \
+	-DCMAKE_CXX_COMPILER=${MPI_INSTALL}/bin/mpicxx \
+	-DCMAKE_Fortran_COMPILER=${MPI_INSTALL}/bin/mpif77 \
+	-DHAVE_ACRO=OFF \
+	-DHAVE_JEGA=OFF \
+	-C${DAK_SRC}/cmake/BuildDakotaCustom.cmake \
+	-C${DAK_SRC}/cmake/DakotaDev.cmake \
+	${DAK_SRC}
+
+# Compile and install
+if [ $# -eq 0 ]; then
+	make
+	make install
+else
+	make -j $1
+	make -j $1 install
+fi
+
+cd ${DAK_INSTALL}
+
+# Comment out definition of HAVE_MPI in Teuchos config header file in order to
+# avoid conflict with our definition
+sed -i -e "s/#define HAVE_MPI/\/* #define HAVE_MPI *\//g" include/Teuchos_config.h
Index: /issm/trunk-jpl/externalpackages/lapack/install-3.8-linux-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/lapack/install-3.8-linux-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/lapack/install-3.8-linux-static.sh	(revision 24593)
@@ -0,0 +1,42 @@
+#!/bin/bash
+set -eu
+
+
+# NOTE: This installation script will build both BLAS and LAPACK libraries
+#
+
+## Constants
+#
+VER="3.8.0"
+
+## Environment
+#
+export CC="${ISSM_DIR}/externalpackages/mpich/install/bin/mpicc"
+export CXX="${ISSM_DIR}/externalpackages/mpich/install/bin/mpicxx"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/lapack-${VER}.tar.gz" "lapack-${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf lapack-${VER}.tar.gz
+
+# Cleanup
+rm -rf build install src
+mkdir build install install/lib src
+
+# Move source to 'src' directory
+mv lapack-${VER}/* src
+rm -rf lapack-${VER}
+
+# Configure
+#
+cd build
+cmake \
+	../src
+
+# Compile
+make
+
+# Install
+cd ..
+cp ./build/lib/* ./install/lib
Index: /issm/trunk-jpl/externalpackages/lapack/install-3.8-linux.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/lapack/install-3.8-linux.sh	(revision 24592)
+++ /issm/trunk-jpl/externalpackages/lapack/install-3.8-linux.sh	(revision 24593)
@@ -10,9 +10,15 @@
 VER="3.8.0"
 
+## Environment
+#
+export CC="${ISSM_DIR}/externalpackages/mpich/install/bin/mpicc"
+export CXX="${ISSM_DIR}/externalpackages/mpich/install/bin/mpicxx"
+export FC="${ISSM_DIR}/externalpackages/mpich/install/bin/mpif77"
+
 # Download source
 $ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/lapack-${VER}.tar.gz" "lapack-${VER}.tar.gz"
 
 # Unpack source
-tar -zxvf lapack-$VER.tar.gz
+tar -zxvf lapack-${VER}.tar.gz
 
 # Cleanup
@@ -21,6 +27,6 @@
 
 # Move source to 'src' directory
-mv lapack-$VER/* src
-rm -rf lapack-$VER
+mv lapack-${VER}/* src
+rm -rf lapack-${VER}
 
 # Configure
Index: /issm/trunk-jpl/externalpackages/mpich/install-3.2-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/mpich/install-3.2-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/mpich/install-3.2-static.sh	(revision 24593)
@@ -0,0 +1,58 @@
+#!/bin/bash
+set -eu
+
+
+## Environment
+#
+export LD_LIBRARY_PATH="" # Ensure that libtool does not hardcode local paths set by running $ISSM_DIR/etc/environment.sh into binaries
+export LD_RUN_PATH="" # Ensure that libtool does not hardcode local paths set by running $ISSM_DIR/etc/environment.sh into binaries
+
+## Constants
+#
+VER="3.2"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/mpich-${VER}.tar.gz" "mpich-${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf mpich-${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install src
+
+# Move source into 'src' directory
+mv mpich-${VER}/* src
+rm -rf mpich-${VER}
+
+# Configure
+cd src
+./configure \
+	--prefix="${ISSM_DIR}/externalpackages/mpich/install" \
+	--disable-shared \
+	--disable-dependency-tracking \
+	--enable-fast=all \
+	--with-pic
+
+# Compile and install
+if [ $# -eq 0 ]; then
+	make
+	make install
+else
+	make -j $1
+	make -j $1 install
+fi
+
+# Return to initial directory
+cd ..
+
+# Strip RPATH/RUNPATH entries from executables
+#
+# NOTE:
+# - We are doing this so that we do not ship executables that have hardcoded
+#	local paths in their RPATH/RUNPATH entries
+# - This might otherwise be accomplished with extensive changes to libtool's
+#	handling of rpath
+#
+chrpath -d ./install/bin/hydra_pmi_proxy
+chrpath -d ./install/bin/mpiexec
Index: /issm/trunk-jpl/externalpackages/mpich/install-3.3-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/mpich/install-3.3-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/mpich/install-3.3-static.sh	(revision 24593)
@@ -0,0 +1,58 @@
+#!/bin/bash
+set -eu
+
+
+## Environment
+#
+export LD_LIBRARY_PATH="" # Ensure that libtool does not hardcode local paths set by running $ISSM_DIR/etc/environment.sh into binaries
+export LD_RUN_PATH="" # Ensure that libtool does not hardcode local paths set by running $ISSM_DIR/etc/environment.sh into binaries
+
+## Constants
+#
+VER="3.3"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/mpich-${VER}.tar.gz" "mpich-${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf mpich-$VER.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install src
+
+# Move source into 'src' directory
+mv mpich-${VER}/* src
+rm -rf mpich-${VER}
+
+# Configure
+cd src
+./configure \
+	--prefix="${ISSM_DIR}/externalpackages/mpich/install" \
+	--disable-shared \
+	--disable-dependency-tracking \
+	--enable-fast=all \
+	--with-pic
+
+# Compile and install
+if [ $# -eq 0 ]; then
+	make
+	make install
+else
+	make -j $1
+	make -j $1 install
+fi
+
+# Return to initial directory
+cd ..
+
+# Strip RPATH/RUNPATH entries from executables
+#
+# NOTE:
+# - We are doing this so that we do not ship executables that have hardcoded
+#	local paths in their RPATH/RUNPATH entries
+# - This might otherwise be accomplished with extensive changes to libtool's
+#	handling of rpath
+#
+chrpath -d ./install/bin/hydra_pmi_proxy
+chrpath -d ./install/bin/mpiexec
Index: /issm/trunk-jpl/externalpackages/mpich/install-3.3.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/mpich/install-3.3.sh	(revision 24592)
+++ /issm/trunk-jpl/externalpackages/mpich/install-3.3.sh	(revision 24593)
@@ -11,5 +11,5 @@
 
 # Unpack source
-tar -zxvf  mpich-$VER.tar.gz
+tar -zxvf mpich-${VER}.tar.gz
 
 # Cleanup
@@ -18,6 +18,6 @@
 
 # Move source into 'src' directory
-mv mpich-$VER/* src
-rm -rf mpich-$VER
+mv mpich-${VER}/* src
+rm -rf mpich-${VER}
 
 # Configure
@@ -25,5 +25,7 @@
 ./configure \
 	--prefix="${ISSM_DIR}/externalpackages/mpich/install" \
-	--enable-shared
+	--disable-static \
+	--disable-dependency-tracking \
+	--enable-fast=all
 
 # Compile and install
@@ -35,5 +37,2 @@
 	make -j $1 install
 fi
-
-# Return to initial directory
-cd ..
Index: /issm/trunk-jpl/externalpackages/mumps/configs/5.0/linux/Makefile.debian.static.PAR
===================================================================
--- /issm/trunk-jpl/externalpackages/mumps/configs/5.0/linux/Makefile.debian.static.PAR	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/mumps/configs/5.0/linux/Makefile.debian.static.PAR	(revision 24593)
@@ -0,0 +1,72 @@
+#
+#  This file is part of MUMPS 5.0.2, released
+#  on Fri Jul 15 09:12:54 UTC 2016
+#
+# These settings for a PC under Debian/linux with standard packages :
+# metis (parmetis), scotch (ptscotch), openmpi, gfortran
+
+# packages installation :
+# apt-get install libmetis-dev libparmetis-dev libscotch-dev libptscotch-dev libatlas-base-dev openmpi-bin libopenmpi-dev
+
+# Begin orderings
+LSCOTCHDIR = ${ISSM_DIR}/externalpackages/petsc/install/lib
+ISCOTCH   = -I${ISSM_DIR}/externalpackages/petsc/install/include # only needed for ptscotch
+
+LSCOTCH   = -L$(LSCOTCHDIR) -lptesmumps -lptscotch -lptscotcherr -lscotch
+#LSCOTCH   = -L$(LSCOTCHDIR) -lesmumps -lscotch -lscotcherr
+
+LPORDDIR = $(topdir)/PORD/lib/
+IPORD    = -I$(topdir)/PORD/include/
+LPORD    = -L$(LPORDDIR) -lpord
+
+LMETISDIR = ${ISSM_DIR}/externalpackages/petsc/install/lib
+IMETIS    = -I${ISSM_DIR}/externalpackages/petsc/install/include
+#IMETIS    = -I/usr/include/metis
+
+LMETIS    = -L$(LMETISDIR) -lparmetis -lmetis
+#LMETIS    = -L$(LMETISDIR) -lmetis
+
+# Corresponding variables reused later
+#ORDERINGSF = -Dmetis -Dpord -Dparmetis -Dscotch -Dptscotch
+ORDERINGSF = -Dmetis -Dpord -Dscotch
+ORDERINGSC  = $(ORDERINGSF)
+LORDERINGS = $(LMETIS) $(LPORD) $(LSCOTCH)
+IORDERINGSF = $(ISCOTCH)
+IORDERINGSC = $(IMETIS) $(IPORD) $(ISCOTCH)
+# End orderings
+################################################################################
+
+PLAT    =
+LIBEXT  = .a
+OUTC    = -o
+OUTF    = -o
+RM = /bin/rm -f
+CC = ${ISSM_DIR}/externalpackages/mpich/install/bin/mpicc
+FC = ${ISSM_DIR}/externalpackages/mpich/install/bin/mpifort
+FL = ${ISSM_DIR}/externalpackages/mpich/install/bin/mpifort
+AR = ar vr
+RANLIB = ranlib
+SCALAP  = -L${ISSM_DIR}/externalpackages/scalapack/install/lib -lscalapack
+
+INCPAR = -I${ISSM_DIR}/externalpackages/mpich/install/include
+
+LIBPAR = $(SCALAP) -L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpifort
+
+INCSEQ = -I$(topdir)/libseq
+LIBSEQ  =  -L$(topdir)/libseq -lmpiseq
+
+LIBBLAS = -L${ISSM_DIR}/externalpackages/openblas/install/lib -lopenblas
+LIBOTHERS = -lpthread
+
+#Preprocessor defs for calling Fortran from C (-DAdd_ or -DAdd__ or -DUPPER)
+CDEFS   = -DAdd_
+
+#Begin Optimized options
+# uncomment -fopenmp in lines below to benefit from OpenMP
+OPTF    = -O  -DALLOW_NON_INIT # -fopenmp
+OPTL    = -O # -fopenmp
+OPTC    = -O # -fopenmp
+#End Optimized options
+INCS = $(INCPAR)
+LIBS = $(LIBPAR)
+LIBSEQNEEDED =
Index: /issm/trunk-jpl/externalpackages/mumps/install-5.0-linux-parallel-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/mumps/install-5.0-linux-parallel-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/mumps/install-5.0-linux-parallel-static.sh	(revision 24593)
@@ -0,0 +1,40 @@
+#!/bin/bash
+set -eu
+
+
+## NOTE: This install script uses make directly rather than CMake and then make
+
+## Constants
+#
+PKG="mumps"
+VER="5.0.2-p2"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/${PKG}-${VER}.tar.gz" "${PKG}-${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf ${PKG}-${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install install/include install/lib src
+
+# Move source to 'src' directory
+mv MUMPS_${VER}/* src
+rm -rf MUMPS_${VER}
+
+# Copy customized source and config files to 'src' directory
+cp configs/5.0/linux/Makefile.debian.static.PAR src/Makefile.inc
+
+# Compile
+cd src
+if [ $# -eq 0 ]; then
+	make
+else
+	make -j $1
+fi
+
+# Install
+cd ..
+cp src/include/* install/include
+cp src/lib/lib*.* install/lib
Index: /issm/trunk-jpl/externalpackages/openblas/install-0.3-linux-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/openblas/install-0.3-linux-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/openblas/install-0.3-linux-static.sh	(revision 24593)
@@ -0,0 +1,44 @@
+#!/bin/bash
+set -eu
+
+
+# NOTE: Full LAPACK implementation is included in OpenBLAS
+#
+
+## Constants
+#
+PKG="OpenBLAS"
+VER="0.3.7"
+
+## Environment
+#
+export CC="${ISSM_DIR}/externalpackages/mpich/install/bin/mpicc"
+export CXX="${ISSM_DIR}/externalpackages/mpich/install/bin/mpicxx"
+export FC="${ISSM_DIR}/externalpackages/mpich/install/bin/mpifort"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/${PKG}-${VER}.tar.gz" "${PKG}-${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf ${PKG}-${VER}.tar.gz
+
+# Cleanup
+rm -rf build install src
+mkdir build install install/lib src
+
+# Move source to 'src' directory
+mv ${PKG}-${VER}/* src
+rm -rf ${PKG}-${VER}
+
+# Configure
+#
+cd build
+cmake \
+	../src
+
+# Compile
+make
+
+# Install
+cd ..
+cp ./build/lib/* ./install/lib
Index: /issm/trunk-jpl/externalpackages/petsc/install-3.7-linux-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/petsc/install-3.7-linux-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/petsc/install-3.7-linux-static.sh	(revision 24593)
@@ -0,0 +1,58 @@
+#!/bin/bash
+set -eu
+
+
+## Constants
+#
+VER="3.7.6"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/petsc-lite-${VER}.tar.gz" "petsc-${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf  petsc-${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install src
+
+# Move source to 'src' directory
+mv petsc-${VER}/* src/
+rm -rf petsc-${VER}
+
+# Configure
+#
+# NOTE:
+# - Despite the fact that the with-pic option is used, external packages
+#	require the fPIC compiler flag to be supplied directly to the compilers in
+#	order for position independent code to be generated.
+#
+cd src
+./config/configure.py \
+	--prefix="${ISSM_DIR}/externalpackages/petsc/install" \
+	--PETSC_DIR="${ISSM_DIR}/externalpackages/petsc/src" \
+	--with-shared-libraries=0 \
+	--with-mpi-dir="${ISSM_DIR}/externalpackages/mpich/install" \
+	--with-blas-lib="-L${ISSM_DIR}/externalpackages/lapack/install/lib -lblas" \
+	--with-lapack-lib="-L${ISSM_DIR}/externalpackages/lapack/install/lib -llapack" \
+	--with-debugging=0 \
+	--with-valgrind=0 \
+	--with-x=0 \
+	--with-ssl=0 \
+	--with-pic=1 \
+	--download-metis=1 \
+	--download-parmetis=1 \
+	--download-scalapack=1 \
+	--download-mumps=1 \
+	--COPTFLAGS="-fPIC" \
+	--CXXOPTFLAGS="-fPIC" \
+	--FOPTFLAGS="-fPIC"
+
+# Compile and install
+if [ $# -eq 0 ]; then
+	make
+	make install
+else
+	make -j $1
+	make -j $1 install
+fi
Index: /issm/trunk-jpl/externalpackages/scalapack/configs/2.0/linux/SLmake.inc.static
===================================================================
--- /issm/trunk-jpl/externalpackages/scalapack/configs/2.0/linux/SLmake.inc.static	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/scalapack/configs/2.0/linux/SLmake.inc.static	(revision 24593)
@@ -0,0 +1,60 @@
+############################################################################
+#
+#  Program:         ScaLAPACK
+#
+#  Module:          SLmake.inc
+#
+#  Purpose:         Top-level Definitions
+#
+#  Creation date:   February 15, 2000
+#
+#  Modified:        October 13, 2011
+#
+#  Send bug reports, comments or suggestions to scalapack@cs.utk.edu
+#
+############################################################################
+#
+#  C preprocessor definitions:  set CDEFS to one of the following:
+#
+#     -DNoChange (fortran subprogram names are lower case without any suffix)
+#     -DUpCase   (fortran subprogram names are upper case without any suffix)
+#     -DAdd_     (fortran subprogram names are lower case with "_" appended)
+
+CDEFS         = -DAdd_
+
+#
+#  The fortran and C compilers, loaders, and their flags
+#
+
+FC            = ${ISSM_DIR}/externalpackages/mpich/install/bin/mpifort
+CC            = ${ISSM_DIR}/externalpackages/mpich/install/bin/mpicc
+NOOPT         = -O0 -fPIC
+FCFLAGS       = -O3 -fPIC
+CCFLAGS       = -O3 -fPIC
+FCLOADER      = $(FC)
+CCLOADER      = $(CC)
+FCLOADFLAGS   = $(FCFLAGS)
+CCLOADFLAGS   = $(CCFLAGS)
+
+#
+#  The archiver and the flag(s) to use when building archive (library)
+#  Also the ranlib routine.  If your system has no ranlib, set RANLIB = echo
+#
+
+ARCH          = ar
+ARCHFLAGS     = cr
+RANLIB        = ranlib
+
+#
+#  The name of the ScaLAPACK library to be created
+#
+
+SCALAPACKLIB  = libscalapack.a
+
+#
+#  BLAS, LAPACK (and possibly other) libraries needed for linking test programs
+#
+
+BLASLIB       = -L${ISSM_DIR}/externalpackages/openblas/install/lib -lopenblas
+LAPACKLIB     = -L${ISSM_DIR}/externalpackages/openblas/install/lib -lopenblas
+LIBS          = $(LAPACKLIB) $(BLASLIB)
Index: /issm/trunk-jpl/externalpackages/scalapack/install-2.0-linux-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/scalapack/install-2.0-linux-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/scalapack/install-2.0-linux-static.sh	(revision 24593)
@@ -0,0 +1,43 @@
+#!/bin/bash
+set -eu
+
+
+## NOTE: This install script uses make directly rather than CMake and then make
+
+## Constants
+#
+PKG="scalapack"
+VER="2.0.2"
+
+## Environment
+#
+export MPI_BASE_DIR="${ISSM_DIR}/externalpackages/mpich/install"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/${PKG}-${VER}.tgz" "${PKG}-${VER}.tgz"
+
+# Unpack source
+tar -zxvf ${PKG}-${VER}.tgz
+
+# Cleanup
+rm -rf build install src
+mkdir build install install/lib src
+
+# Move source to 'src' directory
+mv ${PKG}-${VER}/* src
+rm -rf ${PKG}-${VER}
+
+# Copy customized source and config files to 'src' directory
+cp configs/2.0/linux/SLmake.inc.static src/SLmake.inc
+
+# Compile
+cd src
+if [ $# -eq 0 ]; then
+	make
+else
+	make -j $1
+fi
+
+# Install
+cd ..
+cp ./src/lib*.* ./install/lib
Index: /issm/trunk-jpl/externalpackages/scotch/configs/6.0/linux/Makefile.inc.linux-parallel-static
===================================================================
--- /issm/trunk-jpl/externalpackages/scotch/configs/6.0/linux/Makefile.inc.linux-parallel-static	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/scotch/configs/6.0/linux/Makefile.inc.linux-parallel-static	(revision 24593)
@@ -0,0 +1,21 @@
+EXE		=
+LIB		= .a
+OBJ		= .o
+
+MAKE		= make
+AR		= ar
+ARFLAGS		= -ruv
+CAT		= cat
+CCS		= gcc
+CCP		= ${ISSM_DIR}/externalpackages/mpich/install/bin/mpicc
+CCD		= gcc
+CFLAGS		= -O3 -fPIC -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_PTHREAD -Drestrict=__restrict -DIDXSIZE64
+CLIBFLAGS	=
+LDFLAGS		= -lz -lm -lrt -pthread
+CP		= cp
+LEX		= flex -Pscotchyy -olex.yy.c
+LN		= ln
+MKDIR		= mkdir -p
+MV		= mv
+RANLIB		= ranlib
+YACC		= bison -pscotchyy -y -b y
Index: /issm/trunk-jpl/externalpackages/scotch/install-6.0-linux-parallel-static.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/scotch/install-6.0-linux-parallel-static.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/scotch/install-6.0-linux-parallel-static.sh	(revision 24593)
@@ -0,0 +1,42 @@
+#!/bin/bash
+set -eu
+
+
+## NOTE: This install script uses make directly rather than CMake and then make
+
+## Constants
+#
+PKG="scotch"
+VER="6.0.9"
+
+# Download source
+$ISSM_DIR/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/${PKG}_${VER}.tar.gz" "${PKG}_${VER}.tar.gz"
+
+# Unpack source
+tar -zxvf ${PKG}_${VER}.tar.gz
+
+# Cleanup
+rm -rf install src
+mkdir install install/include install/lib src
+
+# Move source to 'src' directory
+mv ${PKG}_${VER}/* src
+rm -rf ${PKG}_${VER}
+
+# Copy customized source and config files to 'src' directory
+cp configs/6.0/linux/Makefile.inc.linux-parallel-static src/src/Makefile.inc
+
+# Compile
+cd src/src
+if [ $# -eq 0 ]; then
+	make ptscotch
+	make ptesmumps
+else
+	make -j $1 ptscotch
+	make -j $1 ptesmumps
+fi
+
+# Install
+cd ../..
+cp src/include/* install/include
+cp src/lib/lib*.* install/lib
Index: /issm/trunk-jpl/externalpackages/triangle/configs/javascript/triangle.h
===================================================================
--- /issm/trunk-jpl/externalpackages/triangle/configs/javascript/triangle.h	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/triangle/configs/javascript/triangle.h	(revision 24593)
@@ -0,0 +1,296 @@
+/*****************************************************************************/
+/*                                                                           */
+/*  (triangle.h)                                                             */
+/*                                                                           */
+/*  Include file for programs that call Triangle.                            */
+/*                                                                           */
+/*  Accompanies Triangle Version 1.6                                         */
+/*  July 28, 2005                                                            */
+/*                                                                           */
+/*  Copyright 1996, 2005                                                     */
+/*  Jonathan Richard Shewchuk                                                */
+/*  2360 Woolsey #H                                                          */
+/*  Berkeley, California  94705-1927                                         */
+/*  jrs@cs.berkeley.edu                                                      */
+/*                                                                           */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  How to call Triangle from another program                                */
+/*                                                                           */
+/*                                                                           */
+/*  If you haven't read Triangle's instructions (run "triangle -h" to read   */
+/*  them), you won't understand what follows.                                */
+/*                                                                           */
+/*  Triangle must be compiled into an object file (triangle.o) with the      */
+/*  TRILIBRARY symbol defined (generally by using the -DTRILIBRARY compiler  */
+/*  switch).  The makefile included with Triangle will do this for you if    */
+/*  you run "make trilibrary".  The resulting object file can be called via  */
+/*  the procedure triangulate().                                             */
+/*                                                                           */
+/*  If the size of the object file is important to you, you may wish to      */
+/*  generate a reduced version of triangle.o.  The REDUCED symbol gets rid   */
+/*  of all features that are primarily of research interest.  Specifically,  */
+/*  the -DREDUCED switch eliminates Triangle's -i, -F, -s, and -C switches.  */
+/*  The CDT_ONLY symbol gets rid of all meshing algorithms above and beyond  */
+/*  constrained Delaunay triangulation.  Specifically, the -DCDT_ONLY switch */
+/*  eliminates Triangle's -r, -q, -a, -u, -D, -Y, -S, and -s switches.       */
+/*                                                                           */
+/*  IMPORTANT:  These definitions (TRILIBRARY, REDUCED, CDT_ONLY) must be    */
+/*  made in the makefile or in triangle.c itself.  Putting these definitions */
+/*  in this file (triangle.h) will not create the desired effect.            */
+/*                                                                           */
+/*                                                                           */
+/*  The calling convention for triangulate() follows.                        */
+/*                                                                           */
+/*      void triangulate(triswitches, in, out, vorout)                       */
+/*      char *triswitches;                                                   */
+/*      struct triangulateio *in;                                            */
+/*      struct triangulateio *out;                                           */
+/*      struct triangulateio *vorout;                                        */
+/*                                                                           */
+/*  `triswitches' is a string containing the command line switches you wish  */
+/*  to invoke.  No initial dash is required.  Some suggestions:              */
+/*                                                                           */
+/*  - You'll probably find it convenient to use the `z' switch so that       */
+/*    points (and other items) are numbered from zero.  This simplifies      */
+/*    indexing, because the first item of any type always starts at index    */
+/*    [0] of the corresponding array, whether that item's number is zero or  */
+/*    one.                                                                   */
+/*  - You'll probably want to use the `Q' (quiet) switch in your final code, */
+/*    but you can take advantage of Triangle's printed output (including the */
+/*    `V' switch) while debugging.                                           */
+/*  - If you are not using the `q', `a', `u', `D', `j', or `s' switches,     */
+/*    then the output points will be identical to the input points, except   */
+/*    possibly for the boundary markers.  If you don't need the boundary     */
+/*    markers, you should use the `N' (no nodes output) switch to save       */
+/*    memory.  (If you do need boundary markers, but need to save memory, a  */
+/*    good nasty trick is to set out->pointlist equal to in->pointlist       */
+/*    before calling triangulate(), so that Triangle overwrites the input    */
+/*    points with identical copies.)                                         */
+/*  - The `I' (no iteration numbers) and `g' (.off file output) switches     */
+/*    have no effect when Triangle is compiled with TRILIBRARY defined.      */
+/*                                                                           */
+/*  `in', `out', and `vorout' are descriptions of the input, the output,     */
+/*  and the Voronoi output.  If the `v' (Voronoi output) switch is not used, */
+/*  `vorout' may be NULL.  `in' and `out' may never be NULL.                 */
+/*                                                                           */
+/*  Certain fields of the input and output structures must be initialized,   */
+/*  as described below.                                                      */
+/*                                                                           */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  The `triangulateio' structure.                                           */
+/*                                                                           */
+/*  Used to pass data into and out of the triangulate() procedure.           */
+/*                                                                           */
+/*                                                                           */
+/*  Arrays are used to store points, triangles, markers, and so forth.  In   */
+/*  all cases, the first item in any array is stored starting at index [0].  */
+/*  However, that item is item number `1' unless the `z' switch is used, in  */
+/*  which case it is item number `0'.  Hence, you may find it easier to      */
+/*  index points (and triangles in the neighbor list) if you use the `z'     */
+/*  switch.  Unless, of course, you're calling Triangle from a Fortran       */
+/*  program.                                                                 */
+/*                                                                           */
+/*  Description of fields (except the `numberof' fields, which are obvious): */
+/*                                                                           */
+/*  `pointlist':  An array of point coordinates.  The first point's x        */
+/*    coordinate is at index [0] and its y coordinate at index [1], followed */
+/*    by the coordinates of the remaining points.  Each point occupies two   */
+/*    REALs.                                                                 */
+/*  `pointattributelist':  An array of point attributes.  Each point's       */
+/*    attributes occupy `numberofpointattributes' REALs.                     */
+/*  `pointmarkerlist':  An array of point markers; one int per point.        */
+/*                                                                           */
+/*  `trianglelist':  An array of triangle corners.  The first triangle's     */
+/*    first corner is at index [0], followed by its other two corners in     */
+/*    counterclockwise order, followed by any other nodes if the triangle    */
+/*    represents a nonlinear element.  Each triangle occupies                */
+/*    `numberofcorners' ints.                                                */
+/*  `triangleattributelist':  An array of triangle attributes.  Each         */
+/*    triangle's attributes occupy `numberoftriangleattributes' REALs.       */
+/*  `trianglearealist':  An array of triangle area constraints; one REAL per */
+/*    triangle.  Input only.                                                 */
+/*  `neighborlist':  An array of triangle neighbors; three ints per          */
+/*    triangle.  Output only.                                                */
+/*                                                                           */
+/*  `segmentlist':  An array of segment endpoints.  The first segment's      */
+/*    endpoints are at indices [0] and [1], followed by the remaining        */
+/*    segments.  Two ints per segment.                                       */
+/*  `segmentmarkerlist':  An array of segment markers; one int per segment.  */
+/*                                                                           */
+/*  `holelist':  An array of holes.  The first hole's x and y coordinates    */
+/*    are at indices [0] and [1], followed by the remaining holes.  Two      */
+/*    REALs per hole.  Input only, although the pointer is copied to the     */
+/*    output structure for your convenience.                                 */
+/*                                                                           */
+/*  `regionlist':  An array of regional attributes and area constraints.     */
+/*    The first constraint's x and y coordinates are at indices [0] and [1], */
+/*    followed by the regional attribute at index [2], followed by the       */
+/*    maximum area at index [3], followed by the remaining area constraints. */
+/*    Four REALs per area constraint.  Note that each regional attribute is  */
+/*    used only if you select the `A' switch, and each area constraint is    */
+/*    used only if you select the `a' switch (with no number following), but */
+/*    omitting one of these switches does not change the memory layout.      */
+/*    Input only, although the pointer is copied to the output structure for */
+/*    your convenience.                                                      */
+/*                                                                           */
+/*  `edgelist':  An array of edge endpoints.  The first edge's endpoints are */
+/*    at indices [0] and [1], followed by the remaining edges.  Two ints per */
+/*    edge.  Output only.                                                    */
+/*  `edgemarkerlist':  An array of edge markers; one int per edge.  Output   */
+/*    only.                                                                  */
+/*  `normlist':  An array of normal vectors, used for infinite rays in       */
+/*    Voronoi diagrams.  The first normal vector's x and y magnitudes are    */
+/*    at indices [0] and [1], followed by the remaining vectors.  For each   */
+/*    finite edge in a Voronoi diagram, the normal vector written is the     */
+/*    zero vector.  Two REALs per edge.  Output only.                        */
+/*                                                                           */
+/*                                                                           */
+/*  Any input fields that Triangle will examine must be initialized.         */
+/*  Furthermore, for each output array that Triangle will write to, you      */
+/*  must either provide space by setting the appropriate pointer to point    */
+/*  to the space you want the data written to, or you must initialize the    */
+/*  pointer to NULL, which tells Triangle to allocate space for the results. */
+/*  The latter option is preferable, because Triangle always knows exactly   */
+/*  how much space to allocate.  The former option is provided mainly for    */
+/*  people who need to call Triangle from Fortran code, though it also makes */
+/*  possible some nasty space-saving tricks, like writing the output to the  */
+/*  same arrays as the input.                                                */
+/*                                                                           */
+/*  Triangle will not free() any input or output arrays, including those it  */
+/*  allocates itself; that's up to you.  You should free arrays allocated by */
+/*  Triangle by calling the trifree() procedure defined below.  (By default, */
+/*  trifree() just calls the standard free() library procedure, but          */
+/*  applications that call triangulate() may replace trimalloc() and         */
+/*  trifree() in triangle.c to use specialized memory allocators.)           */
+/*                                                                           */
+/*  Here's a guide to help you decide which fields you must initialize       */
+/*  before you call triangulate().                                           */
+/*                                                                           */
+/*  `in':                                                                    */
+/*                                                                           */
+/*    - `pointlist' must always point to a list of points; `numberofpoints'  */
+/*      and `numberofpointattributes' must be properly set.                  */
+/*      `pointmarkerlist' must either be set to NULL (in which case all      */
+/*      markers default to zero), or must point to a list of markers.  If    */
+/*      `numberofpointattributes' is not zero, `pointattributelist' must     */
+/*      point to a list of point attributes.                                 */
+/*    - If the `r' switch is used, `trianglelist' must point to a list of    */
+/*      triangles, and `numberoftriangles', `numberofcorners', and           */
+/*      `numberoftriangleattributes' must be properly set.  If               */
+/*      `numberoftriangleattributes' is not zero, `triangleattributelist'    */
+/*      must point to a list of triangle attributes.  If the `a' switch is   */
+/*      used (with no number following), `trianglearealist' must point to a  */
+/*      list of triangle area constraints.  `neighborlist' may be ignored.   */
+/*    - If the `p' switch is used, `segmentlist' must point to a list of     */
+/*      segments, `numberofsegments' must be properly set, and               */
+/*      `segmentmarkerlist' must either be set to NULL (in which case all    */
+/*      markers default to zero), or must point to a list of markers.        */
+/*    - If the `p' switch is used without the `r' switch, then               */
+/*      `numberofholes' and `numberofregions' must be properly set.  If      */
+/*      `numberofholes' is not zero, `holelist' must point to a list of      */
+/*      holes.  If `numberofregions' is not zero, `regionlist' must point to */
+/*      a list of region constraints.                                        */
+/*    - If the `p' switch is used, `holelist', `numberofholes',              */
+/*      `regionlist', and `numberofregions' is copied to `out'.  (You can    */
+/*      nonetheless get away with not initializing them if the `r' switch is */
+/*      used.)                                                               */
+/*    - `edgelist', `edgemarkerlist', `normlist', and `numberofedges' may be */
+/*      ignored.                                                             */
+/*                                                                           */
+/*  `out':                                                                   */
+/*                                                                           */
+/*    - `pointlist' must be initialized (NULL or pointing to memory) unless  */
+/*      the `N' switch is used.  `pointmarkerlist' must be initialized       */
+/*      unless the `N' or `B' switch is used.  If `N' is not used and        */
+/*      `in->numberofpointattributes' is not zero, `pointattributelist' must */
+/*      be initialized.                                                      */
+/*    - `trianglelist' must be initialized unless the `E' switch is used.    */
+/*      `neighborlist' must be initialized if the `n' switch is used.  If    */
+/*      the `E' switch is not used and (`in->numberofelementattributes' is   */
+/*      not zero or the `A' switch is used), `elementattributelist' must be  */
+/*      initialized.  `trianglearealist' may be ignored.                     */
+/*    - `segmentlist' must be initialized if the `p' or `c' switch is used,  */
+/*      and the `P' switch is not used.  `segmentmarkerlist' must also be    */
+/*      initialized under these circumstances unless the `B' switch is used. */
+/*    - `edgelist' must be initialized if the `e' switch is used.            */
+/*      `edgemarkerlist' must be initialized if the `e' switch is used and   */
+/*      the `B' switch is not.                                               */
+/*    - `holelist', `regionlist', `normlist', and all scalars may be ignored.*/
+/*                                                                           */
+/*  `vorout' (only needed if `v' switch is used):                            */
+/*                                                                           */
+/*    - `pointlist' must be initialized.  If `in->numberofpointattributes'   */
+/*      is not zero, `pointattributelist' must be initialized.               */
+/*      `pointmarkerlist' may be ignored.                                    */
+/*    - `edgelist' and `normlist' must both be initialized.                  */
+/*      `edgemarkerlist' may be ignored.                                     */
+/*    - Everything else may be ignored.                                      */
+/*                                                                           */
+/*  After a call to triangulate(), the valid fields of `out' and `vorout'    */
+/*  will depend, in an obvious way, on the choice of switches used.  Note    */
+/*  that when the `p' switch is used, the pointers `holelist' and            */
+/*  `regionlist' are copied from `in' to `out', but no new space is          */
+/*  allocated; be careful that you don't free() the same array twice.  On    */
+/*  the other hand, Triangle will never copy the `pointlist' pointer (or any */
+/*  others); new space is allocated for `out->pointlist', or if the `N'      */
+/*  switch is used, `out->pointlist' remains uninitialized.                  */
+/*                                                                           */
+/*  All of the meaningful `numberof' fields will be properly set; for        */
+/*  instance, `numberofedges' will represent the number of edges in the      */
+/*  triangulation whether or not the edges were written.  If segments are    */
+/*  not used, `numberofsegments' will indicate the number of boundary edges. */
+/*                                                                           */
+/*****************************************************************************/
+
+/*Patch for ISSM*/
+#ifndef REAL
+typedef double REAL;
+typedef void VOID;
+#endif
+/*End patch*/
+
+struct triangulateio {
+  REAL *pointlist;                                               /* In / out */
+  REAL *pointattributelist;                                      /* In / out */
+  int *pointmarkerlist;                                          /* In / out */
+  int numberofpoints;                                            /* In / out */
+  int numberofpointattributes;                                   /* In / out */
+
+  int *trianglelist;                                             /* In / out */
+  REAL *triangleattributelist;                                   /* In / out */
+  REAL *trianglearealist;                                         /* In only */
+  int *neighborlist;                                             /* Out only */
+  int numberoftriangles;                                         /* In / out */
+  int numberofcorners;                                           /* In / out */
+  int numberoftriangleattributes;                                /* In / out */
+
+  int *segmentlist;                                              /* In / out */
+  int *segmentmarkerlist;                                        /* In / out */
+  int numberofsegments;                                          /* In / out */
+
+  REAL *holelist;                        /* In / pointer to array copied out */
+  int numberofholes;                                      /* In / copied out */
+
+  REAL *regionlist;                      /* In / pointer to array copied out */
+  int numberofregions;                                    /* In / copied out */
+
+  int *edgelist;                                                 /* Out only */
+  int *edgemarkerlist;            /* Not used with Voronoi diagram; out only */
+  REAL *normlist;                /* Used only with Voronoi diagram; out only */
+  int numberofedges;                                             /* Out only */
+};
+
+#ifdef ANSI_DECLARATORS
+void triangulate(char *, struct triangulateio *, struct triangulateio *,
+                 struct triangulateio *);
+void trifree(VOID *memptr);
+#else /* not ANSI_DECLARATORS */
+void triangulate();
+void trifree();
+#endif /* not ANSI_DECLARATORS */
Index: /issm/trunk-jpl/externalpackages/triangle/configs/makefile
===================================================================
--- /issm/trunk-jpl/externalpackages/triangle/configs/makefile	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/triangle/configs/makefile	(revision 24593)
@@ -0,0 +1,43 @@
+################################################################################
+# Adaptation of Triangle makefile to compile only the triangle.c source file
+################################################################################
+include ./configure.make
+
+ifeq "$(origin CC)" "undefined"
+	CC = cc
+endif
+
+ifeq "$(origin AR)" "undefined"
+	AR = ar
+endif
+
+ifeq "$(origin RANLIB)" "undefined"
+	RANLIB = ranlib
+endif
+
+SOURCES=triangle.c triangle.h
+OBJECTS=triangle.$(OBJ_EXT)
+
+all: libtriangle.a libtriangle.$(SHARED_LIB_EXT)
+
+objects: $(OBJECTS)
+
+shared: libtriangle.$(SHARED_LIB_EXT)
+
+static: libtriangle.a
+
+triangle.o: $(SOURCES)
+	$(CC) $(CSWITCHES) $(TRILIBDEFS) -c triangle.c
+
+libtriangle.a: $(OBJECTS)
+	$(AR) cr $@ $(OBJECTS)
+	$(RANLIB) $@
+
+libtriangle.dylib: $(OBJECTS)
+	$(CC) $(CSWITCHES) $(TRILIBDEFS) -dynamiclib -install_name $(PREFIX)/$@ -o $@ triangle.c
+
+libtriangle.so: $(SOURCES)
+	$(CC) $(CSWITCHES) $(TRILIBDEFS) -shared -o $@ triangle.c
+
+clean:
+	rm -rf *.$(LIB_EXT) *.$(OBJ_EXT) *.LIB *.LST *.$(OBJ_EXT)bj *.BAK
Index: /issm/trunk-jpl/externalpackages/triangle/configs/triangle.h
===================================================================
--- /issm/trunk-jpl/externalpackages/triangle/configs/triangle.h	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/triangle/configs/triangle.h	(revision 24593)
@@ -0,0 +1,296 @@
+/*****************************************************************************/
+/*                                                                           */
+/*  (triangle.h)                                                             */
+/*                                                                           */
+/*  Include file for programs that call Triangle.                            */
+/*                                                                           */
+/*  Accompanies Triangle Version 1.6                                         */
+/*  July 28, 2005                                                            */
+/*                                                                           */
+/*  Copyright 1996, 2005                                                     */
+/*  Jonathan Richard Shewchuk                                                */
+/*  2360 Woolsey #H                                                          */
+/*  Berkeley, California  94705-1927                                         */
+/*  jrs@cs.berkeley.edu                                                      */
+/*                                                                           */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  How to call Triangle from another program                                */
+/*                                                                           */
+/*                                                                           */
+/*  If you haven't read Triangle's instructions (run "triangle -h" to read   */
+/*  them), you won't understand what follows.                                */
+/*                                                                           */
+/*  Triangle must be compiled into an object file (triangle.o) with the      */
+/*  TRILIBRARY symbol defined (generally by using the -DTRILIBRARY compiler  */
+/*  switch).  The makefile included with Triangle will do this for you if    */
+/*  you run "make trilibrary".  The resulting object file can be called via  */
+/*  the procedure triangulate().                                             */
+/*                                                                           */
+/*  If the size of the object file is important to you, you may wish to      */
+/*  generate a reduced version of triangle.o.  The REDUCED symbol gets rid   */
+/*  of all features that are primarily of research interest.  Specifically,  */
+/*  the -DREDUCED switch eliminates Triangle's -i, -F, -s, and -C switches.  */
+/*  The CDT_ONLY symbol gets rid of all meshing algorithms above and beyond  */
+/*  constrained Delaunay triangulation.  Specifically, the -DCDT_ONLY switch */
+/*  eliminates Triangle's -r, -q, -a, -u, -D, -Y, -S, and -s switches.       */
+/*                                                                           */
+/*  IMPORTANT:  These definitions (TRILIBRARY, REDUCED, CDT_ONLY) must be    */
+/*  made in the makefile or in triangle.c itself.  Putting these definitions */
+/*  in this file (triangle.h) will not create the desired effect.            */
+/*                                                                           */
+/*                                                                           */
+/*  The calling convention for triangulate() follows.                        */
+/*                                                                           */
+/*      void triangulate(triswitches, in, out, vorout)                       */
+/*      char *triswitches;                                                   */
+/*      struct triangulateio *in;                                            */
+/*      struct triangulateio *out;                                           */
+/*      struct triangulateio *vorout;                                        */
+/*                                                                           */
+/*  `triswitches' is a string containing the command line switches you wish  */
+/*  to invoke.  No initial dash is required.  Some suggestions:              */
+/*                                                                           */
+/*  - You'll probably find it convenient to use the `z' switch so that       */
+/*    points (and other items) are numbered from zero.  This simplifies      */
+/*    indexing, because the first item of any type always starts at index    */
+/*    [0] of the corresponding array, whether that item's number is zero or  */
+/*    one.                                                                   */
+/*  - You'll probably want to use the `Q' (quiet) switch in your final code, */
+/*    but you can take advantage of Triangle's printed output (including the */
+/*    `V' switch) while debugging.                                           */
+/*  - If you are not using the `q', `a', `u', `D', `j', or `s' switches,     */
+/*    then the output points will be identical to the input points, except   */
+/*    possibly for the boundary markers.  If you don't need the boundary     */
+/*    markers, you should use the `N' (no nodes output) switch to save       */
+/*    memory.  (If you do need boundary markers, but need to save memory, a  */
+/*    good nasty trick is to set out->pointlist equal to in->pointlist       */
+/*    before calling triangulate(), so that Triangle overwrites the input    */
+/*    points with identical copies.)                                         */
+/*  - The `I' (no iteration numbers) and `g' (.off file output) switches     */
+/*    have no effect when Triangle is compiled with TRILIBRARY defined.      */
+/*                                                                           */
+/*  `in', `out', and `vorout' are descriptions of the input, the output,     */
+/*  and the Voronoi output.  If the `v' (Voronoi output) switch is not used, */
+/*  `vorout' may be NULL.  `in' and `out' may never be NULL.                 */
+/*                                                                           */
+/*  Certain fields of the input and output structures must be initialized,   */
+/*  as described below.                                                      */
+/*                                                                           */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  The `triangulateio' structure.                                           */
+/*                                                                           */
+/*  Used to pass data into and out of the triangulate() procedure.           */
+/*                                                                           */
+/*                                                                           */
+/*  Arrays are used to store points, triangles, markers, and so forth.  In   */
+/*  all cases, the first item in any array is stored starting at index [0].  */
+/*  However, that item is item number `1' unless the `z' switch is used, in  */
+/*  which case it is item number `0'.  Hence, you may find it easier to      */
+/*  index points (and triangles in the neighbor list) if you use the `z'     */
+/*  switch.  Unless, of course, you're calling Triangle from a Fortran       */
+/*  program.                                                                 */
+/*                                                                           */
+/*  Description of fields (except the `numberof' fields, which are obvious): */
+/*                                                                           */
+/*  `pointlist':  An array of point coordinates.  The first point's x        */
+/*    coordinate is at index [0] and its y coordinate at index [1], followed */
+/*    by the coordinates of the remaining points.  Each point occupies two   */
+/*    REALs.                                                                 */
+/*  `pointattributelist':  An array of point attributes.  Each point's       */
+/*    attributes occupy `numberofpointattributes' REALs.                     */
+/*  `pointmarkerlist':  An array of point markers; one int per point.        */
+/*                                                                           */
+/*  `trianglelist':  An array of triangle corners.  The first triangle's     */
+/*    first corner is at index [0], followed by its other two corners in     */
+/*    counterclockwise order, followed by any other nodes if the triangle    */
+/*    represents a nonlinear element.  Each triangle occupies                */
+/*    `numberofcorners' ints.                                                */
+/*  `triangleattributelist':  An array of triangle attributes.  Each         */
+/*    triangle's attributes occupy `numberoftriangleattributes' REALs.       */
+/*  `trianglearealist':  An array of triangle area constraints; one REAL per */
+/*    triangle.  Input only.                                                 */
+/*  `neighborlist':  An array of triangle neighbors; three ints per          */
+/*    triangle.  Output only.                                                */
+/*                                                                           */
+/*  `segmentlist':  An array of segment endpoints.  The first segment's      */
+/*    endpoints are at indices [0] and [1], followed by the remaining        */
+/*    segments.  Two ints per segment.                                       */
+/*  `segmentmarkerlist':  An array of segment markers; one int per segment.  */
+/*                                                                           */
+/*  `holelist':  An array of holes.  The first hole's x and y coordinates    */
+/*    are at indices [0] and [1], followed by the remaining holes.  Two      */
+/*    REALs per hole.  Input only, although the pointer is copied to the     */
+/*    output structure for your convenience.                                 */
+/*                                                                           */
+/*  `regionlist':  An array of regional attributes and area constraints.     */
+/*    The first constraint's x and y coordinates are at indices [0] and [1], */
+/*    followed by the regional attribute at index [2], followed by the       */
+/*    maximum area at index [3], followed by the remaining area constraints. */
+/*    Four REALs per area constraint.  Note that each regional attribute is  */
+/*    used only if you select the `A' switch, and each area constraint is    */
+/*    used only if you select the `a' switch (with no number following), but */
+/*    omitting one of these switches does not change the memory layout.      */
+/*    Input only, although the pointer is copied to the output structure for */
+/*    your convenience.                                                      */
+/*                                                                           */
+/*  `edgelist':  An array of edge endpoints.  The first edge's endpoints are */
+/*    at indices [0] and [1], followed by the remaining edges.  Two ints per */
+/*    edge.  Output only.                                                    */
+/*  `edgemarkerlist':  An array of edge markers; one int per edge.  Output   */
+/*    only.                                                                  */
+/*  `normlist':  An array of normal vectors, used for infinite rays in       */
+/*    Voronoi diagrams.  The first normal vector's x and y magnitudes are    */
+/*    at indices [0] and [1], followed by the remaining vectors.  For each   */
+/*    finite edge in a Voronoi diagram, the normal vector written is the     */
+/*    zero vector.  Two REALs per edge.  Output only.                        */
+/*                                                                           */
+/*                                                                           */
+/*  Any input fields that Triangle will examine must be initialized.         */
+/*  Furthermore, for each output array that Triangle will write to, you      */
+/*  must either provide space by setting the appropriate pointer to point    */
+/*  to the space you want the data written to, or you must initialize the    */
+/*  pointer to NULL, which tells Triangle to allocate space for the results. */
+/*  The latter option is preferable, because Triangle always knows exactly   */
+/*  how much space to allocate.  The former option is provided mainly for    */
+/*  people who need to call Triangle from Fortran code, though it also makes */
+/*  possible some nasty space-saving tricks, like writing the output to the  */
+/*  same arrays as the input.                                                */
+/*                                                                           */
+/*  Triangle will not free() any input or output arrays, including those it  */
+/*  allocates itself; that's up to you.  You should free arrays allocated by */
+/*  Triangle by calling the trifree() procedure defined below.  (By default, */
+/*  trifree() just calls the standard free() library procedure, but          */
+/*  applications that call triangulate() may replace trimalloc() and         */
+/*  trifree() in triangle.c to use specialized memory allocators.)           */
+/*                                                                           */
+/*  Here's a guide to help you decide which fields you must initialize       */
+/*  before you call triangulate().                                           */
+/*                                                                           */
+/*  `in':                                                                    */
+/*                                                                           */
+/*    - `pointlist' must always point to a list of points; `numberofpoints'  */
+/*      and `numberofpointattributes' must be properly set.                  */
+/*      `pointmarkerlist' must either be set to NULL (in which case all      */
+/*      markers default to zero), or must point to a list of markers.  If    */
+/*      `numberofpointattributes' is not zero, `pointattributelist' must     */
+/*      point to a list of point attributes.                                 */
+/*    - If the `r' switch is used, `trianglelist' must point to a list of    */
+/*      triangles, and `numberoftriangles', `numberofcorners', and           */
+/*      `numberoftriangleattributes' must be properly set.  If               */
+/*      `numberoftriangleattributes' is not zero, `triangleattributelist'    */
+/*      must point to a list of triangle attributes.  If the `a' switch is   */
+/*      used (with no number following), `trianglearealist' must point to a  */
+/*      list of triangle area constraints.  `neighborlist' may be ignored.   */
+/*    - If the `p' switch is used, `segmentlist' must point to a list of     */
+/*      segments, `numberofsegments' must be properly set, and               */
+/*      `segmentmarkerlist' must either be set to NULL (in which case all    */
+/*      markers default to zero), or must point to a list of markers.        */
+/*    - If the `p' switch is used without the `r' switch, then               */
+/*      `numberofholes' and `numberofregions' must be properly set.  If      */
+/*      `numberofholes' is not zero, `holelist' must point to a list of      */
+/*      holes.  If `numberofregions' is not zero, `regionlist' must point to */
+/*      a list of region constraints.                                        */
+/*    - If the `p' switch is used, `holelist', `numberofholes',              */
+/*      `regionlist', and `numberofregions' is copied to `out'.  (You can    */
+/*      nonetheless get away with not initializing them if the `r' switch is */
+/*      used.)                                                               */
+/*    - `edgelist', `edgemarkerlist', `normlist', and `numberofedges' may be */
+/*      ignored.                                                             */
+/*                                                                           */
+/*  `out':                                                                   */
+/*                                                                           */
+/*    - `pointlist' must be initialized (NULL or pointing to memory) unless  */
+/*      the `N' switch is used.  `pointmarkerlist' must be initialized       */
+/*      unless the `N' or `B' switch is used.  If `N' is not used and        */
+/*      `in->numberofpointattributes' is not zero, `pointattributelist' must */
+/*      be initialized.                                                      */
+/*    - `trianglelist' must be initialized unless the `E' switch is used.    */
+/*      `neighborlist' must be initialized if the `n' switch is used.  If    */
+/*      the `E' switch is not used and (`in->numberofelementattributes' is   */
+/*      not zero or the `A' switch is used), `elementattributelist' must be  */
+/*      initialized.  `trianglearealist' may be ignored.                     */
+/*    - `segmentlist' must be initialized if the `p' or `c' switch is used,  */
+/*      and the `P' switch is not used.  `segmentmarkerlist' must also be    */
+/*      initialized under these circumstances unless the `B' switch is used. */
+/*    - `edgelist' must be initialized if the `e' switch is used.            */
+/*      `edgemarkerlist' must be initialized if the `e' switch is used and   */
+/*      the `B' switch is not.                                               */
+/*    - `holelist', `regionlist', `normlist', and all scalars may be ignored.*/
+/*                                                                           */
+/*  `vorout' (only needed if `v' switch is used):                            */
+/*                                                                           */
+/*    - `pointlist' must be initialized.  If `in->numberofpointattributes'   */
+/*      is not zero, `pointattributelist' must be initialized.               */
+/*      `pointmarkerlist' may be ignored.                                    */
+/*    - `edgelist' and `normlist' must both be initialized.                  */
+/*      `edgemarkerlist' may be ignored.                                     */
+/*    - Everything else may be ignored.                                      */
+/*                                                                           */
+/*  After a call to triangulate(), the valid fields of `out' and `vorout'    */
+/*  will depend, in an obvious way, on the choice of switches used.  Note    */
+/*  that when the `p' switch is used, the pointers `holelist' and            */
+/*  `regionlist' are copied from `in' to `out', but no new space is          */
+/*  allocated; be careful that you don't free() the same array twice.  On    */
+/*  the other hand, Triangle will never copy the `pointlist' pointer (or any */
+/*  others); new space is allocated for `out->pointlist', or if the `N'      */
+/*  switch is used, `out->pointlist' remains uninitialized.                  */
+/*                                                                           */
+/*  All of the meaningful `numberof' fields will be properly set; for        */
+/*  instance, `numberofedges' will represent the number of edges in the      */
+/*  triangulation whether or not the edges were written.  If segments are    */
+/*  not used, `numberofsegments' will indicate the number of boundary edges. */
+/*                                                                           */
+/*****************************************************************************/
+
+/*Patch for ISSM*/
+#ifndef REAL
+typedef double REAL;
+typedef void VOID;
+#endif
+/*End patch*/
+
+struct triangulateio {
+  REAL *pointlist;                                               /* In / out */
+  REAL *pointattributelist;                                      /* In / out */
+  int *pointmarkerlist;                                          /* In / out */
+  int numberofpoints;                                            /* In / out */
+  int numberofpointattributes;                                   /* In / out */
+
+  int *trianglelist;                                             /* In / out */
+  REAL *triangleattributelist;                                   /* In / out */
+  REAL *trianglearealist;                                         /* In only */
+  int *neighborlist;                                             /* Out only */
+  int numberoftriangles;                                         /* In / out */
+  int numberofcorners;                                           /* In / out */
+  int numberoftriangleattributes;                                /* In / out */
+
+  int *segmentlist;                                              /* In / out */
+  int *segmentmarkerlist;                                        /* In / out */
+  int numberofsegments;                                          /* In / out */
+
+  REAL *holelist;                        /* In / pointer to array copied out */
+  int numberofholes;                                      /* In / copied out */
+
+  REAL *regionlist;                      /* In / pointer to array copied out */
+  int numberofregions;                                    /* In / copied out */
+
+  int *edgelist;                                                 /* Out only */
+  int *edgemarkerlist;            /* Not used with Voronoi diagram; out only */
+  REAL *normlist;                /* Used only with Voronoi diagram; out only */
+  int numberofedges;                                             /* Out only */
+};
+
+#ifdef ANSI_DECLARATORS
+extern "C" void triangulate(char *, struct triangulateio *, struct triangulateio *,
+                 struct triangulateio *);
+void trifree(VOID *memptr);
+#else /* not ANSI_DECLARATORS */
+void triangulate();
+void trifree();
+#endif /* not ANSI_DECLARATORS */
Index: /issm/trunk-jpl/externalpackages/triangle/install-linux-javascript.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/triangle/install-linux-javascript.sh	(revision 24593)
+++ /issm/trunk-jpl/externalpackages/triangle/install-linux-javascript.sh	(revision 24593)
@@ -0,0 +1,48 @@
+#!/bin/bash
+set -eu
+
+
+# TODO:
+# - Revisit enviroment variables (especially EMCC_CFLAGS) once support for
+#	Fortran has been accomplished.
+#
+
+# Constants
+#
+INSTALL_DIR="install-javascript"
+
+# Environment
+#
+export CC=emcc
+export CXX=em++
+export AR=emar
+export RANLIB=emranlib
+#export EMCC_DEBUG=1 # Uncomment to enable debugging
+export EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0" # Required after v1.38.14 to avoid undefined symbol warnings from our Fortran object files being treated as errors
+
+# Source Emscripten environment
+source ${ISSM_DIR}/externalpackages/emscripten/install/emsdk_env.sh
+
+# Cleanup
+rm -rf ${INSTALL_DIR} src
+mkdir ${INSTALL_DIR} ${INSTALL_DIR}/include ${INSTALL_DIR}/share src
+
+# Download source
+${ISSM_DIR}/scripts/DownloadExternalPackage.sh "https://issm.ess.uci.edu/files/externalpackages/triangle.zip" "triangle.zip"
+
+# Unpack source
+unzip triangle.zip -d src
+
+# Copy customized source files to 'src' directory
+cp configs/makefile src
+cp configs/javascript/configure.make src
+cp configs/javascript/triangle.h src
+
+# Compile
+cd src
+make objects
+
+# Install
+cd ..
+cp src/triangle.o ${INSTALL_DIR}/share
+cp src/triangle.h ${INSTALL_DIR}/include
Index: /issm/trunk-jpl/jenkins/ross-debian_linux
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux	(revision 24593)
@@ -1,30 +1,48 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-# MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-# ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
-	--with-matlab-dir=$MATLAB_PATH \
-	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include \
-	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-chaco-dir=$ISSM_DIR/externalpackages/chaco/install \
-	--with-m1qn3-dir=$ISSM_DIR/externalpackages/m1qn3/install \
-	--with-semic-dir=$ISSM_DIR/externalpackages/semic/install \
-	--with-numthreads=4 \
 	--enable-development \
 	--enable-debugging \
+	--with-numthreads=4 \
+	--with-matlab-dir=${MATLAB_PATH} \
+	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-chaco-dir=${ISSM_DIR}/externalpackages/chaco/install \
+	--with-m1qn3-dir=${ISSM_DIR}/externalpackages/m1qn3/install \
+	--with-semic-dir=${ISSM_DIR}/externalpackages/semic/install \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3.sh
+	lapack		install-3.8-linux.sh
+	petsc		install-3.7-linux.sh
+	triangle	install-linux.sh
+	chaco		install.sh
+	m1qn3		install.sh
+	semic		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # Test suites
@@ -33,27 +51,4 @@
 JAVASCRIPT_TEST=0
 EXAMPLES_TEST=0
-
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-# List of external packages to be installed and their installation scripts
-#
-EXTERNALPACKAGES="
-	autotools	install-debian.sh
-	cmake		install.sh
-	mpich		install-3.3.sh
-	lapack		install-3.8-linux.sh
-	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
-	chaco		install.sh
-	m1qn3		install.sh
-	semic		install.sh
-	shell2junit	install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-adolc-ampioff
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-adolc-ampioff	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-adolc-ampioff	(revision 24593)
@@ -1,34 +1,55 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-#MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-#ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
+	--enable-development \
+	--enable-debugging \
+	--with-numthreads=4 \
 	--without-kriging \
 	--without-kml \
 	--without-GiaIvins \
 	--without-Love \
-	--with-matlab-dir=$MATLAB_PATH \
+	--with-matlab-dir=${MATLAB_PATH} \
 	--with-python-dir=/usr \
 	--with-python-numpy-dir=/usr/local/lib/python2.7/dist-packages/numpy \
 	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
-	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
-	--with-adolc-dir=$ISSM_DIR/externalpackages/adolc/install \
-	--with-numthreads=4 \
-	--enable-development \
-	--enable-debugging \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include  \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-gsl-dir=${ISSM_DIR}/externalpackages/gsl/install \
+	--with-adolc-dir=${ISSM_DIR}/externalpackages/adolc/install \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+# NOTE: The PETSc libraries are compiled but not used as they conflict with
+#		ADOL-C: PETSc is really just being used as an installer for other
+#		external packages.
+#
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3.sh
+	lapack		install-3.8-linux.sh
+	petsc		install-3.7-linux.sh
+	triangle	install-linux.sh
+	gsl			install-linux64.sh
+	adolc		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # Test suites
@@ -37,29 +58,4 @@
 JAVASCRIPT_TEST=0
 EXAMPLES_TEST=0
-
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-#List of external pakages to be installed and their installation scripts
-#
-# NOTE: The PETSc libraries are compiled but not used as they conflict with
-#		ADOL-C: PETSc is really just being used as an installer for other
-#		external packages.
-EXTERNALPACKAGES="
-	autotools	install-debian.sh
-	cmake		install.sh
-	mpich		install-3.3.sh
-	lapack		install-3.8-linux.sh
-	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
-	gsl			install-linux64.sh
-	adolc		install.sh
-	shell2junit	install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-adolc-ampion
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-adolc-ampion	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-adolc-ampion	(revision 24593)
@@ -1,35 +1,57 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-#MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-#ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
+	--enable-development \
+	--enable-debugging \
+	--with-numthreads=4 \
 	--without-kriging \
 	--without-kml \
 	--without-GiaIvins \
 	--without-Love \
-	--with-matlab-dir=$MATLAB_PATH \
+	--with-matlab-dir=${MATLAB_PATH} \
 	--with-python-dir=/usr \
 	--with-python-numpy-dir=/usr/local/lib/python2.7/dist-packages/numpy \
 	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include  \
-	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-ampi-dir=$ISSM_DIR/externalpackages/adjoinablempi/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
-	--with-adolc-dir=$ISSM_DIR/externalpackages/adolc/install \
-	--with-numthreads=4 \
-	--enable-development \
-	--enable-debugging \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include  \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-ampi-dir=${ISSM_DIR}/externalpackages/adjoinablempi/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-gsl-dir=${ISSM_DIR}/externalpackages/gsl/install \
+	--with-adolc-dir=${ISSM_DIR}/externalpackages/adolc/install \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+# NOTE: The PETSc libraries are compiled but not used as they conflict with
+#		ADOL-C: PETSc is really just being used as an installer for other
+#		external packages.
+#
+EXTERNALPACKAGES="
+	autotools		install-debian-linux.sh
+	cmake			install.sh
+	mpich			install-3.3.sh
+	lapack			install-3.8-linux.sh
+	petsc			install-3.7-linux.sh
+	triangle		install-linux.sh
+	gsl				install-linux64.sh
+	adjoinablempi	install.sh
+	adolc			install-withampi.sh
+	shell2junit		install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # PYTHON and MATLAB testing
@@ -38,30 +60,4 @@
 JAVASCRIPT_TEST=0
 EXAMPLES_TEST=0
-
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-#List of external pakages to be installed and their installation scripts
-#
-# NOTE: The PETSc libraries are compiled but not used as they conflict with
-#		ADOL-C: PETSc is really just being used as an installer for other
-#		external packages.
-EXTERNALPACKAGES="
-	autotools		install-debian.sh
-	cmake			install.sh
-	mpich			install-3.3.sh
-	lapack			install-3.8-linux.sh
-	petsc			install-3.7-linux.sh
-	triangle		install-linux64.sh
-	gsl				install-linux64.sh
-	adjoinablempi	install.sh
-	adolc			install-withampi.sh
-	shell2junit		install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-binaries
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-binaries	(revision 24593)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-binaries	(revision 24593)
@@ -0,0 +1,74 @@
+#--------------------#
+# ISSM Configuration #
+#--------------------#
+
+MATLAB_PATH="/usr/local/MATLAB/R2019b"
+
+# NOTE: We can disable dependency tracking in the Autotools because the
+#		binaries should always be a one-time build.
+#
+ISSM_CONFIG='\
+	--prefix=${ISSM_DIR} \
+	--enable-standalone-executables \
+	--enable-standalone-modules \
+	--enable-standalone-libraries \
+	--disable-dependency-tracking \
+	--with-numthreads=4 \
+	--with-pic \
+	--with-matlab-dir=${MATLAB_PATH} \
+	--with-fortran-lib="-L${ISSM_DIR}/lib -lgfortran" \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-chaco-dir=${ISSM_DIR}/externalpackages/chaco/install \
+	--with-m1qn3-dir=${ISSM_DIR}/externalpackages/m1qn3/install \
+	--with-semic-dir=${ISSM_DIR}/externalpackages/semic/install \
+'
+#-------------------#
+# External Packages #
+#-------------------#
+
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3-static.sh
+	lapack		install-3.8-linux-static.sh
+	petsc		install-3.7-linux-static.sh
+	triangle	install-linux-static.sh
+	chaco		install.sh
+	m1qn3		install.sh
+	semic		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
+
+# Test suites
+MATLAB_TEST=0
+PYTHON_TEST=0
+JAVASCRIPT_TEST=0
+EXAMPLES_TEST=0
+
+# Number of CPUs used in ISSM compilation
+#
+# NOTE: One is usually safer as some packages are very sensitive to parallel
+# 		compilation.
+#
+NUMCPUS_INSTALL=1
+
+# Number of CPUs used in the nightly runs
+NUMCPUS_RUN=1
+
+# Nightly run options
+#
+# See documentation in test/NightlyRun/runme.* for more information.
+#
+MATLAB_NROPTIONS=""
+PYTHON_NROPTIONS=""
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-binaries-with_dakota
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-binaries-with_dakota	(revision 24593)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-binaries-with_dakota	(revision 24593)
@@ -0,0 +1,82 @@
+#--------------------#
+# ISSM Configuration #
+#--------------------#
+
+MATLAB_PATH="/usr/local/MATLAB/R2019b"
+
+# NOTE: We can disable dependency tracking in the Autotools because the
+#		binaries should always be a one-time build.
+#
+ISSM_CONFIG='\
+	--prefix="${ISSM_DIR}" \
+	--enable-standalone-executables \
+	--enable-standalone-modules \
+	--enable-standalone-libraries \
+	--disable-dependency-tracking \
+	--with-cxxoptflags="-std=c++11" \
+	--with-numthreads=4 \
+	--with-pic \
+	--with-matlab-dir=${MATLAB_PATH} \
+	--with-python-dir=/usr \
+	--with-python-numpy-dir=/usr/local/lib/python2.7/dist-packages/numpy \
+	--with-fortran-lib="-L${ISSM_DIR}/lib -lgfortran" \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-dakota-dir=${ISSM_DIR}/externalpackages/dakota/install \
+	--with-boost-dir=${ISSM_DIR}/externalpackages/boost/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-chaco-dir=${ISSM_DIR}/externalpackages/chaco/install \
+	--with-m1qn3-dir=${ISSM_DIR}/externalpackages/m1qn3/install \
+	--with-semic-dir=${ISSM_DIR}/externalpackages/semic/install \
+'
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3-static.sh
+	lapack		install-3.8-linux-static.sh
+	petsc		install-3.7-linux-static.sh
+	boost		install-1.55-linux-static.sh
+	dakota		install-6.2-linux-static.sh
+	triangle	install-linux-static.sh
+	chaco		install.sh
+	m1qn3		install.sh
+	semic		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
+
+# Test suites
+MATLAB_TEST=0
+PYTHON_TEST=0
+JAVASCRIPT_TEST=0
+EXAMPLES_TEST=0
+
+# Number of CPUs used in ISSM compilation
+#
+# NOTE: One is usually safer as some packages are very sensitive to parallel
+# 		compilation.
+#
+NUMCPUS_INSTALL=1
+
+# Number of CPUs used in the nightly runs
+NUMCPUS_RUN=1
+
+# Nightly run options
+#
+# See documentation in test/NightlyRun/runme.* for more information.
+#
+MATLAB_NROPTIONS=""
+PYTHON_NROPTIONS=""
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-codipack
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-codipack	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-codipack	(revision 24593)
@@ -1,55 +1,45 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-# MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-# ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
+	--enable-tape-alloc \
+	--enable-development \
+	--enable-debugging \
+	--with-numthreads=4 \
 	--without-kriging \
 	--without-kml \
 	--without-GiaIvins \
 	--without-Love \
-	--with-matlab-dir=$MATLAB_PATH \
+	--with-matlab-dir=${MATLAB_PATH} \
 	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-chaco-dir=$ISSM_DIR/externalpackages/chaco/install \
-	--with-m1qn3-dir=$ISSM_DIR/externalpackages/m1qn3/install \
-	--with-semic-dir=$ISSM_DIR/externalpackages/semic/install \
-	--with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
-	--with-medipack-dir="$ISSM_DIR/externalpackages/medipack/install" \
-	--with-codipack-dir="$ISSM_DIR/externalpackages/codipack/install" \
-	--with-numthreads=4 \
-	--enable-tape-alloc \
-	--enable-development \
-	--enable-debugging \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-chaco-dir=${ISSM_DIR}/externalpackages/chaco/install \
+	--with-m1qn3-dir=${ISSM_DIR}/externalpackages/m1qn3/install \
+	--with-semic-dir=${ISSM_DIR}/externalpackages/semic/install \
+	--with-gsl-dir=${ISSM_DIR}/externalpackages/gsl/install \
+	--with-medipack-dir="${ISSM_DIR}/externalpackages/medipack/install" \
+	--with-codipack-dir="${ISSM_DIR}/externalpackages/codipack/install" \
 '
 
-# Test suites
-MATLAB_TEST=1
-PYTHON_TEST=0
-JAVASCRIPT_TEST=0
-EXAMPLES_TEST=0
+#-------------------#
+# External Packages #
+#-------------------#
 
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-#List of external pakages to be installed and their installation scripts
 EXTERNALPACKAGES="
-	autotools	install-debian.sh
+	autotools	install-debian-linux.sh
 	cmake		install.sh
 	mpich		install-3.3.sh
 	lapack		install-3.8-linux.sh
 	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
+	triangle	install-linux.sh
 	chaco		install.sh
 	m1qn3		install.sh
@@ -61,7 +51,13 @@
 "
 
-#-----------------#
-# 4: test options #
-#-----------------#
+#---------#
+# Testing #
+#---------#
+
+# Test suites
+MATLAB_TEST=1
+PYTHON_TEST=0
+JAVASCRIPT_TEST=0
+EXAMPLES_TEST=0
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-dakota
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-dakota	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-dakota	(revision 24593)
@@ -1,34 +1,56 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-#MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-#ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
-	--with-matlab-dir=$MATLAB_PATH \
+	--enable-development \
+	--enable-debugging \
+	--with-cxxoptflags="-std=c++11" \
+	--with-pic \
+	--with-numthreads=4 \
+	--with-matlab-dir=${MATLAB_PATH} \
 	--with-python-dir=/usr \
 	--with-python-numpy-dir=/usr/local/lib/python2.7/dist-packages/numpy \
 	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include \
-	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-chaco-dir=$ISSM_DIR/externalpackages/chaco/install \
-	--with-dakota-dir=$ISSM_DIR/externalpackages/dakota/install \
-	--with-boost-dir=$ISSM_DIR/externalpackages/boost/install \
-	--with-cxxoptflags="-std=c++11" \
-	--with-m1qn3-dir=$ISSM_DIR/externalpackages/m1qn3/install \
-	--with-numthreads=4 \
-	--enable-development \
-	--enable-debugging \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-dakota-dir=${ISSM_DIR}/externalpackages/dakota/install \
+	--with-boost-dir=${ISSM_DIR}/externalpackages/boost/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-chaco-dir=${ISSM_DIR}/externalpackages/chaco/install \
+	--with-m1qn3-dir=${ISSM_DIR}/externalpackages/m1qn3/install \
+	--with-semic-dir=${ISSM_DIR}/externalpackages/semic/install \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3.sh
+	lapack		install-3.8-linux.sh
+	petsc		install-3.7-linux.sh
+	boost		install-1.55-linux.sh
+	dakota		install-6.2-linux.sh
+	triangle	install-linux.sh
+	chaco		install.sh
+	m1qn3		install.sh
+	semic		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # Test suites
@@ -37,27 +59,4 @@
 JAVASCRIPT_TEST=0
 EXAMPLES_TEST=0
-
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-#List of external pakages to be installed and their installation scripts
-EXTERNALPACKAGES="
-	autotools	install-debian.sh
-	cmake		install.sh
-	mpich		install-3.3.sh
-	lapack		install-3.8-linux.sh
-	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
-	boost		install-1.55-linux.sh
-	dakota		install-6.2-linux64.sh
-	chaco		install.sh
-	m1qn3		install.sh
-	shell2junit	install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-gia
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-gia	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-gia	(revision 24593)
@@ -1,31 +1,48 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-#MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-#ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
-	--with-matlab-dir=$MATLAB_PATH \
+	--enable-development \
+	--enable-debugging \
+	--with-gia=yes \
+	--with-numthreads=4
+	--with-matlab-dir=${MATLAB_PATH} \
 	--with-python-dir=/usr \
 	--with-python-numpy-dir=/usr/lib/python2.7/dist-packages/numpy \
 	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include \
-	--with-mpi-libflags="-L$ISSM_DIR/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-math77-dir=$ISSM_DIR/externalpackages/math77/install \
-	--with-gia=yes \
-	--with-numthreads=4 \
-	--enable-development \
-	--enable-debugging \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-math77-dir=${ISSM_DIR}/externalpackages/math77/install \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3.sh
+	lapack		install-3.8-linux.sh
+	petsc		install-3.7-linux.sh
+	triangle	install-linux.sh
+	math77		install.sh
+	gmsh		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # Test suites
@@ -34,25 +51,4 @@
 JAVASCRIPT_TEST=0
 EXAMPLES_TEST=0
-
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-#List of external pakages to be installed and their installation scripts
-EXTERNALPACKAGES="
-	autotools	install-debian.sh
-	cmake		install.sh
-	mpich		install-3.3.sh
-	lapack		install-3.8-linux.sh
-	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
-	math77		install.sh
-	gmsh		install.sh
-	shell2junit	install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-iceocean
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-iceocean	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-iceocean	(revision 24593)
@@ -1,31 +1,49 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-# MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-# ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
-	--with-ocean \
-	--with-matlab-dir=$MATLAB_PATH \
-	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include \
-	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-chaco-dir=$ISSM_DIR/externalpackages/chaco/install \
-	--with-m1qn3-dir=$ISSM_DIR/externalpackages/m1qn3/install \
-	--with-semic-dir=$ISSM_DIR/externalpackages/semic/install \
-	--with-numthreads=4 \
 	--enable-development \
 	--enable-debugging \
+	--with-ocean \
+	--with-numthreads=4 \
+	--with-matlab-dir=${MATLAB_PATH} \
+	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
+	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-chaco-dir=${ISSM_DIR}/externalpackages/chaco/install \
+	--with-m1qn3-dir=${ISSM_DIR}/externalpackages/m1qn3/install \
+	--with-semic-dir=${ISSM_DIR}/externalpackages/semic/install \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3.sh
+	lapack		install-3.8-linux.sh
+	petsc		install-3.7-linux.sh
+	triangle	install-linux.sh
+	chaco		install.sh
+	m1qn3		install.sh
+	semic		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # Test suites
@@ -34,26 +52,4 @@
 JAVASCRIPT_TEST=0
 EXAMPLES_TEST=0
-
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-#List of external pakages to be installed and their installation scripts
-EXTERNALPACKAGES="
-	autotools	install-debian.sh
-	cmake		install.sh
-	mpich		install-3.3.sh
-	lapack		install-3.8-linux.sh
-	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
-	chaco		install.sh
-	m1qn3		install.sh
-	semic		install.sh
-	shell2junit	install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-javascript
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-javascript	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-javascript	(revision 24593)
@@ -1,10 +1,11 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-# ISSM CONFIGURATION
 ISSM_CONFIG='\
-    --prefix=$ISSM_DIR \
+    --prefix=${ISSM_DIR} \
     --disable-shared \
+    --enable-development \
+    --enable-debugging \
     --with-javascript \
     --without-fortran \
@@ -13,7 +14,24 @@
     --without-kml \
     --without-kriging \
-    --with-gsl-dir="$ISSM_DIR/externalpackages/gsl/install-javascript" \
+    --with-gsl-dir="${ISSM_DIR}/externalpackages/gsl/install-javascript" \
     --with-triangle-dir="${ISSM_DIR}/externalpackages/triangle/install-javascript" \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+EXTERNALPACKAGES="
+    autotools   install-debian-linux.sh
+    cmake       install.sh
+    emscripten  install.sh
+    gsl         install-javascript.sh
+    triangle    install-javascript.sh
+    shell2junit install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # Test suites
@@ -23,26 +41,8 @@
 EXAMPLES_TEST=0
 
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-#List of external pakages to be installed and their installation scripts
-EXTERNALPACKAGES="
-    autotools   install-debian.sh
-    cmake       install.sh
-	emscripten	install.sh
-	gsl			install-javascript.sh
-	triangle	install-javascript.sh
-	shell2junit	install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
-
 # Number of CPUs used in ISSM compilation
 #
 # NOTE: One is usually safer as some packages are very sensitive to parallel
-# 		compilation.
+#       compilation.
 #
 NUMCPUS_INSTALL=8
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-python
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-python	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-python	(revision 24593)
@@ -1,28 +1,52 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-#ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
+	--enable-development \
+	--enable-debugging \
+	--with-numthreads=4 \
 	--with-python-dir=/usr \
 	--with-python-numpy-dir=/usr/local/lib/python2.7/dist-packages/numpy \
 	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
 	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-chaco-dir=$ISSM_DIR/externalpackages/chaco/install \
-	--with-m1qn3-dir=$ISSM_DIR/externalpackages/m1qn3/install \
-	--with-semic-dir=$ISSM_DIR/externalpackages/semic/install \
-	--with-numthreads=4 \
-	--enable-development \
-	--enable-debugging \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-chaco-dir=${ISSM_DIR}/externalpackages/chaco/install \
+	--with-m1qn3-dir=${ISSM_DIR}/externalpackages/m1qn3/install \
+	--with-semic-dir=${ISSM_DIR}/externalpackages/semic/install \
 '
+
+#-------------------#
+# External Packages #
+#-------------------#
+
+# TODO:
+# - After upgrading Jenkins nodes to Ubuntu 18, use MPICH 3.3 and PETSc 3.11
+#	(which will install zlib, HDF5, and NetCDF).
+#
+EXTERNALPACKAGES="
+	autotools	install-debian-linux.sh
+	cmake		install.sh
+	mpich		install-3.3.sh
+	lapack		install-3.8-linux.sh
+	petsc		install-3.7-linux.sh
+	triangle	install-linux.sh
+	chaco		install.sh
+	m1qn3		install.sh
+	semic		install.sh
+	shell2junit	install.sh
+"
+
+#---------#
+# Testing #
+#---------#
 
 # Test suites
@@ -31,31 +55,4 @@
 JAVASCRIPT_TEST=0
 EXAMPLES_TEST=0
-
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-# List of external packages to be installed and their installation scripts
-#
-# TODO:
-# - After upgrading Jenkins nodes to Ubuntu 18, use MPICH 3.3 and PETSc 3.11
-#	(which will install zlib, HDF5, and NetCDF).
-#
-EXTERNALPACKAGES="
-	autotools	install-debian.sh
-	cmake		install.sh
-	mpich		install-3.3.sh
-	lapack		install-3.8-linux.sh
-	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
-	chaco		install.sh
-	m1qn3		install.sh
-	semic		install.sh
-	shell2junit	install.sh
-"
-
-#-----------------#
-# 4: test options #
-#-----------------#
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/jenkins/ross-debian_linux-solid_earth
===================================================================
--- /issm/trunk-jpl/jenkins/ross-debian_linux-solid_earth	(revision 24592)
+++ /issm/trunk-jpl/jenkins/ross-debian_linux-solid_earth	(revision 24593)
@@ -1,49 +1,39 @@
-#-------------------------------#
-# 1: ISSM general configuration #
-#-------------------------------#
+#--------------------#
+# ISSM Configuration #
+#--------------------#
 
-#MATLAB path
 MATLAB_PATH="/usr/local/MATLAB/R2019b"
-
-#ISSM CONFIGURATION
 ISSM_CONFIG='\
-	--prefix=$ISSM_DIR \
+	--prefix=${ISSM_DIR} \
 	--disable-static \
-	--with-matlab-dir=$MATLAB_PATH \
+	--enable-development \
+	--enable-debugging \
+	--with-numthreads=4 \
+	--with-matlab-dir=${MATLAB_PATH} \
 	--with-python-dir=/usr \
 	--with-python-numpy-dir=/usr/local/lib/python2.7/dist-packages/numpy \
 	--with-fortran-lib="-L/usr/lib/gcc/x86_64-linux-gnu/8 -lgfortran" \
-	--with-mpi-include=$ISSM_DIR/externalpackages/mpich/install/include \
+	--with-mpi-include=${ISSM_DIR}/externalpackages/mpich/install/include \
 	--with-mpi-libflags="-L${ISSM_DIR}/externalpackages/mpich/install/lib -lmpi -lmpicxx -lmpifort" \
-	--with-blas-lapack-dir=$ISSM_DIR/externalpackages/lapack/install \
-	--with-metis-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-scalapack-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-mumps-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-petsc-dir=$ISSM_DIR/externalpackages/petsc/install \
-	--with-triangle-dir=$ISSM_DIR/externalpackages/triangle/install \
-	--with-boost-dir=$ISSM_DIR/externalpackages/boost/install \
-	--with-numthreads=4 \
-	--enable-development \
-	--enable-debugging \
+	--with-blas-lapack-dir=${ISSM_DIR}/externalpackages/lapack/install \
+	--with-metis-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-scalapack-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-mumps-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-petsc-dir=${ISSM_DIR}/externalpackages/petsc/install \
+	--with-triangle-dir=${ISSM_DIR}/externalpackages/triangle/install \
+	--with-boost-dir=${ISSM_DIR}/externalpackages/boost/install \
 '
 
-# Test suites
-MATLAB_TEST=1
-PYTHON_TEST=1
-JAVASCRIPT_TEST=0
-EXAMPLES_TEST=0
+#-------------------#
+# External Packages #
+#-------------------#
 
-#-----------------------------------#
-# 3: External packages installation #
-#-----------------------------------#
-
-# List of external packages to be installed and their installation scripts
 EXTERNALPACKAGES="
-	autotools	install-debian.sh
+	autotools	install-debian-linux.sh
 	cmake		install.sh
 	mpich		install-3.3.sh
 	lapack		install-3.8-linux.sh
 	petsc		install-3.7-linux.sh
-	triangle	install-linux64.sh
+	triangle	install-linux.sh
 	chaco		install.sh
 	m1qn3		install.sh
@@ -62,7 +52,13 @@
 "
 
-#-----------------#
-# 4: test options #
-#-----------------#
+#---------#
+# Testing #
+#---------#
+
+# Test suites
+MATLAB_TEST=1
+PYTHON_TEST=1
+JAVASCRIPT_TEST=0
+EXAMPLES_TEST=0
 
 # Number of CPUs used in ISSM compilation
Index: /issm/trunk-jpl/m4/issm_options.m4
===================================================================
--- /issm/trunk-jpl/m4/issm_options.m4	(revision 24592)
+++ /issm/trunk-jpl/m4/issm_options.m4	(revision 24593)
@@ -1,6 +1,19 @@
 dnl ISSM Options
 
+dnl TODO:
+dnl - Check if we need statements such as,
+dnl
+dnl.  	  AM_CONDITIONAL([JAVASCRIPT], [test "x${HAVE_JAVASCRIPT}" = "xyes"])
+dnl
+dnl	  when we have already performed a similar check,
+dnl
+dnl  	  if test "x${JAVASCRIPT}" = "xno"; then
+dnl
+dnl - Move library dependency checks from end of file to appropriate places
+dnl   inline
+dnl - Refactor conditionals that test both -d <file> and -f <file>
+dnl
+
 AC_DEFUN([ISSM_OPTIONS],[
-
 	AC_MSG_NOTICE(============================================================================)
 	AC_MSG_NOTICE(=                      Checking ISSM specific options                      =)
@@ -10,16 +23,16 @@
 	dnl Build info{{{
 
-	dnl build date
+	dnl Build date
 	AC_PATH_PROGS(DATE, date)
-	AC_MSG_CHECKING(for build date)
-	if test "$DATE" ; then
+	AC_MSG_CHECKING([for build date])
+	if test "$DATE"; then
 		PACKAGE_DATE=`date`
 	else
 		PACKAGE_DATE="unknown"
 	fi
-	AC_DEFINE_UNQUOTED(PACKAGE_BUILD_DATE,"$PACKAGE_DATE", Build date)
-	AC_MSG_RESULT($PACKAGE_DATE)
-
-	dnl user name
+	AC_DEFINE_UNQUOTED(PACKAGE_BUILD_DATE, "$PACKAGE_DATE", [build date])
+	AC_MSG_RESULT([${PACKAGE_DATE}])
+
+	dnl User name
 	AC_MSG_CHECKING([user name])
 	if test -n "$USER"
@@ -27,131 +40,140 @@
 		user_name="$USER"
 	else
-		if test -n "$LOGNAME"
-		then
-			user_name="$LOGNAME"
+		if test -n "$LOGNAME"; then
+			user_name ="$LOGNAME"
 		else
-		   user_name=`(whoami) 2>/dev/null` || user_name=unknown
-		fi
-	fi
-	AC_DEFINE_UNQUOTED(USER_NAME, "$user_name", Build user name)
-	AC_MSG_RESULT($user_name)
+			user_name =`(whoami) 2>/dev/null` || user_name=unknown
+		fi
+	fi
+	AC_DEFINE_UNQUOTED(USER_NAME, "$user_name", [user name])
+	AC_MSG_RESULT([${user_name}])
 
 	AC_MSG_CHECKING([host full OS name and version])
-	dnl normalize some host OS names
+	dnl Normalize some host OS names
 	case ${host_os} in
-	  dnl linux is linux is linux, regardless of RMS.
-	  linux-gnu* | lignux* )	host_os=linux ;;
+		dnl linux is linux is linux, regardless of RMS
+		linux-gnu* | lignux* )	host_os=linux ;;
 	esac
-	AC_DEFINE_UNQUOTED(HOST_OS, "$host_os", Host full OS name and version)
-	AC_MSG_RESULT($host_os)
-
-  AC_MSG_CHECKING([host cpu])
-  AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu",Host cpu)
-  AC_MSG_RESULT($host_cpu)
-
-  AC_MSG_CHECKING([vendor])
-  AC_DEFINE_UNQUOTED(HOST_VENDOR, "$host_vendor",Host vendor)
-  AC_MSG_RESULT($host_vendor)
-
-  AC_MSG_CHECKING([host OS name])
-  host_os_name=`echo $host_os | sed 's/\..*//g'`
-  dnl normalize some OS names
-  case ${host_os_name} in
-	dnl linux is linux is linux, regardless of RMS.
-	linux-gnu* | lignux* )	host_os_name=linux ;;
-  esac
-  AC_DEFINE_UNQUOTED(HOST_OS_NAME, "$host_os_name", Host OS name)
-  AC_MSG_RESULT($host_os_name)
-
-	dnl parse out the OS version of the host
-  AC_MSG_CHECKING([host OS version])
-  host_os_version=`echo $host_os | sed 's/^[[^0-9]]*//g'`
-  if test -z "$host_os_version"
-  then
-	host_os_version=`(uname -r) 2>/dev/null` || host_os_version=unknown
-  fi
-  AC_DEFINE_UNQUOTED(HOST_OS_VERSION, "$host_os_version", Host OS version)
-  AC_MSG_RESULT($host_os_version)
-
-
-	dnl figure out host architecture (different than CPU)
-  AC_MSG_CHECKING([host OS architecture])
-  host_arch=`(uname -m) 2>/dev/null` || host_arch=unknown
-  dnl normalize some names
-  case ${host_arch} in
-	sun4* )	host_arch=sun4 ;;
-	sun3x )	host_arch=sun3 ;;
-	sun )	host_arch=`(arch) 2>/dev/null` || host_arch=unknown ;;
-	i?86 )	host_arch=i386 ;; # all x86 should show up as i386
-  esac
-  AC_DEFINE_UNQUOTED(HOST_ARCH, "$host_arch",Host Archictecture)
-  AC_MSG_RESULT($host_arch)
+	AC_DEFINE_UNQUOTED(HOST_OS, "$host_os", [host full OS name and version])
+	AC_MSG_RESULT([${host_os}])
+
+	AC_MSG_CHECKING([host cpu])
+	AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu", [host CPU])
+	AC_MSG_RESULT([${host_cpu}])
+
+	AC_MSG_CHECKING([vendor])
+	AC_DEFINE_UNQUOTED(HOST_VENDOR, "$host_vendor", [host vendor])
+	AC_MSG_RESULT([${host_vendor}])
+
+	AC_MSG_CHECKING([host OS name])
+	host_os_name=`echo $host_os | sed 's/\..*//g'`
+	dnl Normalize some OS names
+	case ${host_os_name} in
+		dnl linux is linux is linux, regardless of RMS.
+		linux-gnu* | lignux* )	host_os_name=linux ;;
+	esac
+	AC_DEFINE_UNQUOTED(HOST_OS_NAME, "$host_os_name", [host OS name])
+	AC_MSG_RESULT([${host_os_name}])
+
+	dnl Parse out the OS version of the host
+	AC_MSG_CHECKING([host OS version])
+	host_os_version=`echo $host_os | sed 's/^[[^0-9]]*//g'`
+	if test -z "$host_os_version"; then
+		host_os_version=`(uname -r) 2>/dev/null` || host_os_version=unknown
+	fi
+	AC_DEFINE_UNQUOTED(HOST_OS_VERSION, "$host_os_version", [host OS version])
+	AC_MSG_RESULT([${host_os_version}])
+
+	dnl Determine host architecture (different than CPU)
+	AC_MSG_CHECKING([host OS architecture])
+	host_arch=`(uname -m) 2>/dev/null` || host_arch=unknown
+	dnl Normalize some names
+	case ${host_arch} in
+		sun4* )	host_arch=sun4 ;;
+		sun3x )	host_arch=sun3 ;;
+		sun )	host_arch=`(arch) 2>/dev/null` || host_arch=unknown ;;
+		i?86 )	host_arch=i386 ;; # all x86 should show up as i386
+	esac
+	AC_DEFINE_UNQUOTED(HOST_ARCH, "$host_arch", [host archictecture])
+	AC_MSG_RESULT([${host_arch}])
 
 	dnl }}}
 	dnl Debugging {{{
-	AC_ARG_ENABLE([debugging],                                        dnl feature
-		AS_HELP_STRING([--enable-debugging],[turn debug support on]),  dnl help string
-		[enable_debugging=$enableval],                                 dnl action if given
-		[enable_debugging=no])                                         dnl action if not given
-
+	AC_ARG_ENABLE(
+		[debugging],													dnl feature
+		AS_HELP_STRING([--enable-debugging], [turn debug support on]),	dnl help string
+		[enable_debugging=${enableval}],								dnl action if given
+		[enable_debugging=no]											dnl action if not given
+	)
 	AC_MSG_CHECKING(for debugging support)
-	if test "x$enable_debugging" = xyes; then
-		AC_DEFINE([_ISSM_DEBUG_],[1],[Macro to enable debugging in ISSM])
-	fi
-	AC_MSG_RESULT($enable_debugging)
+	if test "x${enable_debugging}" == "xyes"; then
+		AC_DEFINE([_ISSM_DEBUG_], [1], [Macro to enable debugging in ISSM])
+	fi
+	AC_MSG_RESULT([${enable_debugging}])
 	dnl }}}
 	dnl Development{{{
-	AC_ARG_ENABLE([development],                                      dnl feature
-		AS_HELP_STRING([--enable-development],[turn development on]),  dnl help string
-		[enable_development=$enableval],                                 dnl action if given
-		[enable_development=no])                                      dnl action if not given
-
+	AC_ARG_ENABLE(
+		[development],													dnl feature
+		AS_HELP_STRING([--enable-development], [turn development on]),  dnl help string
+		[enable_development=${enableval}],								dnl action if given
+		[enable_development=no]											dnl action if not given
+	)
 	AC_MSG_CHECKING(for development support)
-	if test "x$enable_development" = xyes; then
-		AC_DEFINE([_DEVELOPMENT_],[1],[Macro to enable development version in ISSM])
-	fi
-	AM_CONDITIONAL([DEVELOPMENT], [test x$enable_development = xyes])
-	AC_MSG_RESULT($enable_development)
-	 dnl }}}
-    dnl Standalone Options {{{
-    AC_ARG_ENABLE([standalone-modules],                                                      dnl feature
-        AS_HELP_STRING([--enable-standalone-modules], [produce standalone modules]),         dnl help string
-        [enable_standalone_modules=$enableval],                                              dnl action if given
-        [enable_standalone_modules=no])                                                      dnl action if not given
+	if test "x${enable_development}" == "xyes"; then
+		AC_DEFINE([_DEVELOPMENT_], [1], [enable development support in ISSM])
+	fi
+	AM_CONDITIONAL([DEVELOPMENT], [test "x${enable_development}" == "xyes"])
+	AC_MSG_RESULT([${enable_development}])
+	dnl }}}
+	dnl Standalone Options {{{
+	AC_ARG_ENABLE(
+		[standalone-modules],															dnl feature
+		AS_HELP_STRING([--enable-standalone-modules], [produce standalone modules]),	dnl help string
+		[enable_standalone_modules=${enableval}],										dnl action if given
+		[enable_standalone_modules=no]													dnl action if not given
+	)
 	AC_MSG_CHECKING(for standalone modules build)
-    AM_CONDITIONAL([STANDALONE_MODULES], [test x$enable_standalone_modules = xyes])
-	AC_MSG_RESULT($enable_standalone_modules)
-
-    AC_ARG_ENABLE([standalone-executables],                                                  dnl feature
-        AS_HELP_STRING([--enable-standalone-executables], [produce standalone executables]), dnl help string
-        [enable_standalone_executables=$enableval],                                          dnl action if given
-        [enable_standalone_executables=no])                                                  dnl action if not given
+	AM_CONDITIONAL([STANDALONE_MODULES], [test "x${enable_standalone_modules}" == "xyes"])
+	AC_MSG_RESULT([${enable_standalone_modules}])
+
+	AC_ARG_ENABLE(
+		[standalone-executables],																dnl feature
+		AS_HELP_STRING([--enable-standalone-executables], [produce standalone executables]),	dnl help string
+		[enable_standalone_executables=${enableval}],											dnl action if given
+		[enable_standalone_executables=no]														dnl action if not given
+	)
 	AC_MSG_CHECKING(for standalone executables build)
-    AM_CONDITIONAL([STANDALONE_EXECUTABLES], [test x$enable_standalone_executables = xyes])
-	AC_MSG_RESULT($enable_standalone_executables)
-
-    AC_ARG_ENABLE([standalone-libraries],                                                    dnl feature
-        AS_HELP_STRING([--enable-standalone-libraries], [produce standalone libraries]),     dnl help string
-        [enable_standalone_libraries=$enableval],                                            dnl action if given
-        [enable_standalone_libraries=no])                                                    dnl action if not given
+	AM_CONDITIONAL([STANDALONE_EXECUTABLES], [test "x${enable_standalone_executables}" == "xyes"])
+	AC_MSG_RESULT([${enable_standalone_executables}])
+
+	AC_ARG_ENABLE(
+		[standalone-libraries],																dnl feature
+		AS_HELP_STRING([--enable-standalone-libraries], [produce standalone libraries]),	dnl help string
+		[enable_standalone_libraries=${enableval}],											dnl action if given
+		[enable_standalone_libraries=no]													dnl action if not given
+	)
 	AC_MSG_CHECKING(for standalone libraries build)
-    AM_CONDITIONAL([STANDALONE_LIBRARIES], [test x$enable_standalone_libraries = xyes])
-	AC_MSG_RESULT($enable_standalone_libraries)
-    dnl }}}
-    dnl Version{{{
-    AC_ARG_ENABLE([version],                                   dnl feature
-    AS_HELP_STRING([--enable-version],[produce libISSM.so.0]), dnl help string
-    [enable_version=$enableval],                               dnl action if given
-    [enable_version=no])                                       dnl action if not given
-    AM_CONDITIONAL([VERSION], [test x$enable_VERSION = xyes])
-    dnl }}}
+	AM_CONDITIONAL([STANDALONE_LIBRARIES], [test "x${enable_standalone_libraries}" == "xyes"])
+	AC_MSG_RESULT([${enable_standalone_libraries}])
+	dnl }}}
+	dnl Version{{{
+	AC_ARG_ENABLE(
+		[version],													dnl feature
+		AS_HELP_STRING([--enable-version], [produce libISSM.so.0]),	dnl help string
+		[enable_version=${enableval}],								dnl action if given
+		[enable_version=no]											dnl action if not given
+	)
+	AM_CONDITIONAL([VERSION], [test "x${enable_version}" == "xyes"])
+	dnl }}}
 	dnl Wrappers build {{{
-	AC_ARG_WITH([wrappers],                                           dnl feature
-	AS_HELP_STRING([--with-wrappers = value],[wrappers compilation]), dnl help string
-	[WRAPPERS_VALUE=$withval],                                        dnl action if given
-	[WRAPPERS_VALUE="yes"])                                           dnl action if not given
+	AC_ARG_WITH(
+		[wrappers],															dnl feature
+		AS_HELP_STRING([--with-wrappers = value], [wrappers compilation]),	dnl help string
+		[WRAPPERS_VALUE=${withval}],										dnl action if given
+		[WRAPPERS_VALUE="yes"]												dnl action if not given
+	)
 	AC_MSG_CHECKING(for wrappers compilation)
-	AM_CONDITIONAL([WRAPPERS], [test x$WRAPPERS_VALUE = xyes])
-	AC_MSG_RESULT($WRAPPERS_VALUE)
+	AM_CONDITIONAL([WRAPPERS], [test "x${WRAPPERS_VALUE}" == "xyes"])
+	AC_MSG_RESULT([${WRAPPERS_VALUE}])
 	dnl }}}
 	dnl Extensions{{{
@@ -162,11 +184,13 @@
 	dnl ISSM's externalpackages
 	dnl vendor{{{
-	AC_ARG_WITH([vendor],                                              dnl feature
-	AS_HELP_STRING([--with-vendor = VENDOR],[vendor name, ex: intel]), dnl help string
-	[VENDOR=$withval],                                                 dnl action if given
-	[VENDOR=""])                                                       dnl action if not given
+	AC_ARG_WITH(
+		[vendor],															dnl feature
+		AS_HELP_STRING([--with-vendor = VENDOR], [vendor name, ex: intel]),	dnl help string
+		[VENDOR=${withval}],												dnl action if given
+		[VENDOR=""]															dnl action if not given
+	)
 	AC_MSG_CHECKING(for vendor compilers)
-	if test -n "$VENDOR"; then
-		if  test $VENDOR = intel-win32; then
+	if test -n "${VENDOR}"; then
+		if test "${VENDOR}" == "intel-win32"; then
 			export CC=icl
 			export CXX=icl
@@ -174,5 +198,5 @@
 			export CXXFLAGS="-DWIN32 -D_INTEL_WIN_"
 			IS_WINDOWS=yes
-		elif  test $VENDOR = intel-win7-32; then
+		elif test "${VENDOR}" == "intel-win7-32"; then
 			export CC=cl
 			export CXX=cl
@@ -184,5 +208,5 @@
 			IS_WINDOWS=yes
 			OSLIBS="-Wl,kernel32.lib -Wl,user32.lib -Wl,gdi32.lib -Wl,winspool.lib -Wl,comdlg32.lib -Wl,advapi32.lib -Wl,shell32.lib -Wl,ole32.lib -Wl,oleaut32.lib -Wl,uuid.lib -Wl,odbc32.lib -Wl,odbccp32.lib"
-		elif  test $VENDOR = intel-win7-64; then
+		elif test "${VENDOR}" == "intel-win7-64"; then
 			export CC=cl
 			export CXX=cl
@@ -194,5 +218,5 @@
 			IS_WINDOWS=yes
 			OSLIBS="-Wl,kernel32.lib -Wl,user32.lib -Wl,gdi32.lib -Wl,winspool.lib -Wl,comdlg32.lib -Wl,advapi32.lib -Wl,shell32.lib -Wl,ole32.lib -Wl,oleaut32.lib -Wl,uuid.lib -Wl,odbc32.lib -Wl,odbccp32.lib"
-		elif  test $VENDOR = MSVC-Win64; then
+		elif test "${VENDOR}" == "MSVC-Win64"; then
 			export CC=cl
 			export CXX=cl
@@ -204,5 +228,5 @@
 			IS_WINDOWS=yes
 			OSLIBS="-Wl,kernel32.lib -Wl,user32.lib -Wl,gdi32.lib -Wl,winspool.lib -Wl,comdlg32.lib -Wl,advapi32.lib -Wl,shell32.lib -Wl,ole32.lib -Wl,oleaut32.lib -Wl,uuid.lib -Wl,odbc32.lib -Wl,odbccp32.lib"
-		elif  test $VENDOR = MSVC-Win64-par; then
+		elif test "${VENDOR}" == "MSVC-Win64-par"; then
 			export CC=cl
 			export CXX=cl
@@ -214,421 +238,452 @@
 			IS_WINDOWS=yes
 			OSLIBS="-Wl,kernel32.lib -Wl,user32.lib -Wl,gdi32.lib -Wl,winspool.lib -Wl,comdlg32.lib -Wl,advapi32.lib -Wl,shell32.lib -Wl,ole32.lib -Wl,oleaut32.lib -Wl,uuid.lib -Wl,odbc32.lib -Wl,odbccp32.lib"
-		elif test $VENDOR = intel-linux; then
+		elif test "${VENDOR}" == "intel-linux"; then
 			export CC=icc
 			export CXX=icpc
-			export CFLAGS=" -D_INTEL_LINUX_"
-			export CXXFLAGS=" -D_INTEL_LINUX_"
-		elif test $VENDOR = intel-gp; then
+			export CFLAGS="-D_INTEL_LINUX_"
+			export CXXFLAGS="-D_INTEL_LINUX_"
+		elif test "${VENDOR}" == "intel-gp"; then
 			export CC=icc
 			export CXX=icpc
-			export CFLAGS=" -D_INTEL_LINUX_"
-			export CXXFLAGS=" -D_INTEL_LINUX_"
-		elif test $VENDOR = intel-lonestar; then
+			export CFLAGS="-D_INTEL_LINUX_"
+			export CXXFLAGS="-D_INTEL_LINUX_"
+		elif test "${VENDOR}" == intel-lonestar; then
 			export CC=icc
 			export CXX=icpc
-		elif test $VENDOR = intel-aurora; then
+		elif test "${VENDOR}" == "intel-aurora"; then
 			export CC=icc
 			export CXX=icpc
-			export CXXFLAGS=" -O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
-			export CFLAGS=" -O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
-		elif test $VENDOR = intel-discover; then
+			export CXXFLAGS="-O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
+			export CFLAGS="-O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
+		elif test "${VENDOR}" == "intel-discover"; then
 			export CC=icc
 			export CXX=icpc
-			export CXXFLAGS=" -O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
-			export CFLAGS=" -O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
-		elif test $VENDOR = intel-pleiades; then
+			export CXXFLAGS="-O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
+			export CFLAGS="-O3 -D_INTEL_LINUX_ -DMPICH_IGNORE_CXX_SEEK"
+		elif test "${VENDOR}" == "intel-pleiades"; then
 			export CC=icc
 			export CXX=icpc
-			export CXXFLAGS=" -O3 -D_INTEL_LINUX_ "
-			export CFLAGS=" -O3 -D_INTEL_LINUX_ "
-		elif test $VENDOR = intel-acenet; then
+			export CXXFLAGS="-O3 -D_INTEL_LINUX_"
+			export CFLAGS="-O3 -D_INTEL_LINUX_"
+		elif test "${VENDOR}" == "intel-acenet"; then
 			export CC=icc
 			export CXX=icpc
-			export CXXFLAGS=" -D_INTEL_LINUX_ "
-			export CFLAGS=" -D_INTEL_LINUX_ "
-		elif test $VENDOR = intel-pleiades-gcc; then
+			export CXXFLAGS="-D_INTEL_LINUX_"
+			export CFLAGS="-D_INTEL_LINUX_"
+		elif test "${VENDOR}" == "intel-pleiades-gcc"; then
 			export CC=gcc
 			export CXX=g++
 			export CXXFLAGS="-O3 -march=corei7-avx"
 			export CFLAGS="-O3 -march=corei7-avx"
-        else
-		AC_MSG_ERROR([unknown compiler vendor!])
+		else
+			AC_MSG_ERROR([unknown compiler vendor!])
 		fi
 	fi
 	AC_SUBST([OSLIBS])
-	AC_MSG_RESULT(done)
-	dnl }}}
-	dnl matlab{{{
-
-	dnl 1. See if matlab has been provided
-	AC_ARG_WITH([matlab-dir],                                         dnl feature
-	AS_HELP_STRING([--with-matlab-dir=DIR],[matlab root directory.]), dnl help string
-	[MATLAB_ROOT=$withval],                                           dnl action if given
-	[MATLAB_ROOT="no"])                                               dnl action if not given
-
-	AC_MSG_CHECKING([whether matlab is enabled])
-	if test "x$MATLAB_ROOT" = "xno" ; then
-		 HAVE_MATLAB=no
+	AC_MSG_RESULT([done])
+	dnl }}}
+	dnl MATLAB{{{
+
+	dnl See if MATLAB has been provided
+	AC_ARG_WITH(
+		[matlab-dir],														dnl feature
+		AS_HELP_STRING([--with-matlab-dir=DIR], [MATLAB root directory]),	dnl help string
+		[MATLAB_ROOT=${withval}],											dnl action if given
+		[MATLAB_ROOT="no"]													dnl action if not given
+	)
+	if test "x${MATLAB_ROOT}" == "xno"; then
+		HAVE_MATLAB=no
 	else
 		HAVE_MATLAB=yes
-		if ! test -d "$MATLAB_ROOT"; then
-		  AC_MSG_ERROR([matlab directory provided ($MATLAB_ROOT) does not exist]);
-		fi
-		if ! test -f "$MATLAB_ROOT/extern/include/mex.h"; then
-			AC_MSG_ERROR([Couldn't find mex.h... check your installation of matlab])
-	   fi
-	fi
-	AC_MSG_RESULT($HAVE_MATLAB)
-	AM_CONDITIONAL([MATLAB], [test x$HAVE_MATLAB = xyes])
-
-	dnl 2. Get Matlab libraries
-	if test "x$HAVE_MATLAB" = "xyes"; then
-
-		AC_DEFINE([_HAVE_MATLAB_],[1],[with matlab in ISSM src])
-
-		dnl 4. get MEXLIB MEXLINK and MEXEXT (experimental) except for windows
-		AC_MSG_CHECKING([matlab's mex compilation flags])
-  		case "${host_os}" in
-  			*cygwin*)
-  				if  test $VENDOR = intel-win7-32; then
-  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
-               MEXLINK="-Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win32/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
-					MEXEXT=`$MATLAB_ROOT/bin/mexext.bat`
-					MEXEXT=".$MEXEXT"
-  				elif test $VENDOR = intel-win7-64; then
-  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
-               MEXLINK="-Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
+		if ! test -d "${MATLAB_ROOT}"; then
+			AC_MSG_ERROR([MATLAB directory provided (${MATLAB_ROOT}) does not exist!]);
+		fi
+		if ! test -f "${MATLAB_ROOT}/extern/include/mex.h"; then
+			AC_MSG_ERROR([Couldn't find mex.h... check your installation of MATLAB])
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_MATLAB}])
+	AM_CONDITIONAL([MATLAB], [test "x${HAVE_MATLAB}" == "xyes"])
+
+	dnl Set variables
+	if test "x${HAVE_MATLAB}" == "xyes"; then
+		AC_DEFINE([_HAVE_MATLAB_], [1], [with MATLAB in ISSM src])
+
+		dnl Set MEXLIB, MEXLINK, and MEXEXT
+		AC_MSG_CHECKING([MATLAB's mex compilation flags])
+
+		dnl NOTE: We know $VENDOR cannot be empty at this point, so no need to
+		dnl		  check again in the following conditionals
+		dnl
+		case "${host_os}" in
+			*cygwin*)
+				if test "${VENDOR}" == "intel-win7-32"; then
+					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
+					MEXLINK="-Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win32/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
+					MEXEXT=`${MATLAB_ROOT}/bin/mexext.bat`
+					MEXEXT=".${MEXEXT}"
+				elif test "${VENDOR}" == "intel-win7-64"; then
+					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
+					MEXLINK="-Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
 					MEXEXT=".mexw64"
-  				elif test $VENDOR = MSVC-Win64 || test $VENDOR = MSVC-Win64-par; then
-  					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
-               MEXLINK="-Wl,/link -Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
-  					MATLABINCL="-I`cygpath -m $MATLAB_ROOT/extern/include/`"
+				elif test "${VENDOR}" == "MSVC-Win64" || test "${VENDOR}" == "MSVC-Win64-par"; then
+					MEXLIB="-Wl,libmx.lib -Wl,libmex.lib -Wl,libmat.lib ${OSLIBS} -Wl,libf2cblas.lib -Wl,libf2clapack.lib"
+					MEXLINK="-Wl,/link -Wl,/LIBPATH:`cygpath -m ${MATLAB_ROOT}/extern/lib/win64/microsoft` -Wl,/link -Wl,/EXPORT:mexFunction -Wl,/DLL"
+					MATLABINCL="-I`cygpath -m ${MATLAB_ROOT}/extern/include`"
 					MEXEXT=".mexw64"
-  				fi
-  			;;
-		   *)
-           MATLABINCL="-I$MATLAB_ROOT/extern/include/"
-           MEXLINK=$($MATLAB_ROOT/bin/mex -v 2>&1 < /dev/null | grep LDFLAGS     | sed -e "s/         LDFLAGS            = //g")
-			  MEXLIB=$( $MATLAB_ROOT/bin/mex -v 2>&1 < /dev/null | grep CXXLIBS     | sed -e "s/         CXXLIBS            = //g")
-		     MEXEXT=$( $MATLAB_ROOT/bin/mex -v 2>&1 < /dev/null | grep LDEXTENSION | sed -e "s/         LDEXTENSION        = //g")
+				fi
+			;;
+			*)
+				MATLABINCL="-I${MATLAB_ROOT}/extern/include"
+				MEXLINK=$(${MATLAB_ROOT}/bin/mex -v 2>&1 < /dev/null | grep LDFLAGS | sed -e "s/         LDFLAGS            = //g")
+				MEXLIB=$(${MATLAB_ROOT}/bin/mex -v 2>&1 < /dev/null | grep CXXLIBS | sed -e "s/         CXXLIBS            = //g")
+				MEXEXT=$(${MATLAB_ROOT}/bin/mex -v 2>&1 < /dev/null | grep LDEXTENSION | sed -e "s/         LDEXTENSION        = //g")
 				dnl version 2014 and up
-				if test "x$MEXEXT" = "x" ; then
-					 echo "#include <mex.h>" > conftest.cpp
-					 echo "void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){}" >> conftest.cpp
-					 $MATLAB_ROOT/bin/mex -v -lmex conftest.cpp > conftest.tmp 2>&1
-					 rm -f conftest.cpp
-					 MEXLINK=$(cat conftest.tmp | grep LDFLAGS  | sed -e "s/LDFLAGS ://g")
-					 MEXLIB=$( cat conftest.tmp | grep LINKLIBS | sed -e "s/LINKLIBS ://g")
-					 MEXEXT=$( cat conftest.tmp | grep LDEXT    | sed -e "s/LDEXT ://g" | awk '{print $[1]}')
-					 rm -f conftest.tmp
+				if test -z "${MEXEXT}"; then
+					echo "#include <mex.h>" > conftest.cpp
+					echo "void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){}" >> conftest.cpp
+					${MATLAB_ROOT}/bin/mex -v -lmex conftest.cpp > conftest.tmp 2>&1
+					rm -f conftest.cpp
+					MEXLINK=$(cat conftest.tmp | grep LDFLAGS | sed -e "s/LDFLAGS ://g")
+					MEXLIB=$(cat conftest.tmp | grep LINKLIBS | sed -e "s/LINKLIBS ://g")
+					MEXEXT=$(cat conftest.tmp | grep LDEXT | sed -e "s/LDEXT ://g" | awk '{print $[1]}')
+					rm -f conftest.tmp
 				fi
 
 				dnl Make sure mexFunction.map is not in MEXLIB to avoid problems with global variables
-				dnl MEXLINK=$(echo $MEXLINK | sed -e "s/,-expo.*mexFunction\\.map\"//g" | sed -e "s/-[[^ ]]*mexFunction\\.map//g")
+				dnl MEXLINK=$(echo ${MEXLINK} | sed -e "s/,-expo.*mexFunction\\.map\"//g" | sed -e "s/-[[^ ]]*mexFunction\\.map//g")
 				MEXLINK="" dnl We actually don't need MEXLINK????
-
-  			;;
-      esac
-		AC_MSG_RESULT(done)
-	   if test "x$MEXEXT" = "x" ; then
-			AC_MSG_ERROR([Couldn't find mex... check your installation of matlab])
-	   fi
+			;;
+		esac
+		AC_MSG_RESULT([done])
+		if test -z "${MEXEXT}"; then
+			AC_MSG_ERROR([Couldn't find mex... check your installation of MATLAB])
+		fi
 
 		AC_SUBST([MATLABINCL])
-		MATLABWRAPPEREXT=$MEXEXT
+		MATLABWRAPPEREXT=${MEXEXT}
 		AC_SUBST([MATLABWRAPPEREXT])
-	   AC_SUBST([MEXLIB])
+		AC_SUBST([MEXLIB])
 		AC_SUBST([MEXLINK])
 	fi
 	dnl }}}
-	dnl windows {{{
-	AC_MSG_CHECKING([Checking if this is a Win build... ])
-	AM_CONDITIONAL([WINDOWS], [test x$IS_WINDOWS = xyes])
-	AC_MSG_RESULT(done)
-	dnl }}}
-	dnl javascript{{{
-	AC_ARG_WITH([javascript],
-	  AS_HELP_STRING([--with-javascript], [compile javascript wrappers? default is no.]),
-	  [JAVASCRIPT=$withval],[JAVASCRIPT="no"])
-
-	dnl Check whether javascript wrappers are desired
-	AC_MSG_CHECKING([for javascript])
-	if test "x$JAVASCRIPT" = "xno" ; then
+	dnl Windows {{{
+	AC_MSG_CHECKING([Checking if this is a Windows build... ])
+	AM_CONDITIONAL([WINDOWS], [test "x${IS_WINDOWS}" == "xyes"])
+	AC_MSG_RESULT([done])
+	dnl }}}
+	dnl JavaScript{{{
+	AC_ARG_WITH(
+		[javascript],
+		AS_HELP_STRING([--with-javascript], [compile JavaScript wrappers? (default: no)]),
+		[JAVASCRIPT=${withval}],
+		[JAVASCRIPT="no"]
+	)
+	AC_MSG_CHECKING([for JavaScript])
+	if test "x${JAVASCRIPT}" == "xno"; then
 		HAVE_JAVASCRIPT=no
 	else
 		HAVE_JAVASCRIPT=yes
-		AC_DEFINE([_HAVE_JAVASCRIPT_],[1],[with javascript])
-	fi
-	AC_MSG_RESULT($HAVE_JAVASCRIPT)
-	AM_CONDITIONAL([JAVASCRIPT],[test x$HAVE_JAVASCRIPT = xyes])
+		AC_DEFINE([_HAVE_JAVASCRIPT_], [1], [with JavaScript])
+	fi
+	AC_MSG_RESULT([${HAVE_JAVASCRIPT}])
+	AM_CONDITIONAL([JAVASCRIPT], [test "x${HAVE_JAVASCRIPT}" == "xyes"])
 	JAVASCRIPTWRAPPEREXT=.js
 	AC_SUBST([JAVASCRIPTWRAPPEREXT])
-
-	dnl }}}
-	dnl triangle {{{
-	AC_ARG_WITH([triangle-dir],
-			  AS_HELP_STRING([--with-triangle-dir=DIR], [triangle root directory.]),
-			 [TRIANGLE_ROOT=$withval],[TRIANGLE_ROOT="no"])
-
-  dnl Check whether triangle is enabled
-  dnl TODO: After discussing with group, uncomment the following lines to
-  dnl		replace the existing ones (where applicable), update Jenkins config
-  dnl		files, then cleanup $ISSM_DIR/externalpackages/triangle.
+	dnl }}}
+	dnl Triangle {{{
+	AC_ARG_WITH(
+		[triangle-dir],
+		AS_HELP_STRING([--with-triangle-dir=DIR], [Triangle root directory]),
+		[TRIANGLE_ROOT=${withval}],
+		[TRIANGLE_ROOT="no"]
+	)
 	AC_MSG_CHECKING([for triangle])
-	if test "x$TRIANGLE_ROOT" = "xno" ; then
+	if test "x${TRIANGLE_ROOT}" == "xno"; then
 		HAVE_TRIANGLE=no
 	else
 		HAVE_TRIANGLE=yes
-		if ! test -d "$TRIANGLE_ROOT"; then
-			AC_MSG_ERROR([triangle directory provided ($TRIANGLE_ROOT) does not exist]);
-		fi
-		if ! test -f "$TRIANGLE_ROOT/triangle.h" ; then
+		if ! test -d "${TRIANGLE_ROOT}"; then
+			AC_MSG_ERROR([Triangle directory provided (${TRIANGLE_ROOT}) does not exist!]);
+		fi
+		if ! test -f "${TRIANGLE_ROOT}/include/triangle.h"; then
 			AC_MSG_ERROR([Couldn't find triangle.h... check your installation of triangle])
 		fi
-		dnl if ! test -f "${TRIANGLE_ROOT}/include/triangle.h" ; then
-			dnl AC_MSG_ERROR([Couldn't find triangle.h... check your installation of triangle])
-		dnl fi
-	fi
-	AC_MSG_RESULT($HAVE_TRIANGLE)
-	AM_CONDITIONAL([TRIANGLE],[test x$HAVE_TRIANGLE = xyes])
-
-	dnl library and header files
-	if test "x$HAVE_TRIANGLE" = "xyes"; then
-		TRIANGLEINCL=-I${TRIANGLE_ROOT}
-		dnl TRIANGLEINCL=-I${TRIANGLE_ROOT}/include
+	fi
+	AC_MSG_RESULT([${HAVE_TRIANGLE}])
+	AM_CONDITIONAL([TRIANGLE], [test "x${HAVE_TRIANGLE}" == "xyes"])
+
+	dnl Triangle libraries and header files
+	if test "x${HAVE_TRIANGLE}" == "xyes"; then
+		TRIANGLEINCL=-I${TRIANGLE_ROOT}/include
 		case "${host_os}" in
 			*cygwin*)
-			TRIANGLEINCL="/I`cygpath -m $TRIANGLE_ROOT/`"
-			TRIANGLELIB="-Wl,`cygpath -m $TRIANGLE_ROOT/`triangle.lib"
+				TRIANGLEINCL="/I`cygpath -m ${TRIANGLE_ROOT}`"
+				TRIANGLELIB="-Wl,`cygpath -m ${TRIANGLE_ROOT}/`triangle.lib"
+			;;
+			*darwin*)
+				if test "x${HAVE_JAVASCRIPT}" == "xyes"; then
+					dnl Link to the object file, not the library
+					TRIANGLELIB=${TRIANGLE_ROOT}/share/triangle.o
+				else
+					TRIANGLELIB="-L${TRIANGLE_ROOT}/lib -ltriangle"
+				fi
 			;;
 			*linux*)
-			if test "x$HAVE_JAVASCRIPT" = "xyes"; then
-				dnl go to the bit code, not the library.
-				TRIANGLELIB=${TRIANGLE_ROOT}/triangle.o
-				dnl TRIANGLELIB=${TRIANGLE_ROOT}/share/triangle.o
-			else
-				TRIANGLELIB=$TRIANGLE_ROOT/triangle.a
-				dnl TRIANGLELIB="-L${TRIANGLE_ROOT}/lib -ltriangle"
-			fi
-			;;
-			*darwin*)
-			if test "x$HAVE_JAVASCRIPT" = "xyes"; then
-				dnl go to the bit code, not the library.
-				TRIANGLELIB=$TRIANGLE_ROOT/triangle.o
-				dnl TRIANGLELIB=${TRIANGLE_ROOT}/share/triangle.o
-			else
-				TRIANGLELIB=$TRIANGLE_ROOT/triangle.a
-				dnl TRIANGLELIB="-L${TRIANGLE_ROOT}/lib -ltriangle"
-			fi
+				if test "x${HAVE_JAVASCRIPT}" == "xyes"; then
+					dnl Link to the object file, not the library
+					TRIANGLELIB=${TRIANGLE_ROOT}/share/triangle.o
+				else
+					TRIANGLELIB="-L${TRIANGLE_ROOT}/lib -ltriangle"
+				fi
 			;;
 		esac
-		AC_DEFINE([_HAVE_TRIANGLE_],[1],[with Triangle in ISSM src])
+		AC_DEFINE([_HAVE_TRIANGLE_], [1], [with Triangle in ISSM src])
 		AC_SUBST([TRIANGLEINCL])
 		AC_SUBST([TRIANGLELIB])
 	fi
 	dnl }}}
-	dnl boost{{{
-	AC_ARG_WITH([boost-dir],
-	  AS_HELP_STRING([--with-boost-dir=DIR], [boost root directory.]),
-	  [BOOST_ROOT=$withval],[BOOST_ROOT="no"])
-
-	dnl Check whether boost is enabled
-	AC_MSG_CHECKING([for boost])
-	if test "x$BOOST_ROOT" = "xno" ; then
+	dnl Boost{{{
+	AC_ARG_WITH(
+		[boost-dir],
+		AS_HELP_STRING([--with-boost-dir=DIR], [Boost root directory]),
+		[BOOST_ROOT=${withval}],
+		[BOOST_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for Boost])
+	if test "x${BOOST_ROOT}" == "xno"; then
 		HAVE_BOOST=no
 	else
 		HAVE_BOOST=yes
-		if ! test -d "$BOOST_ROOT"; then
-			AC_MSG_ERROR([boost directory provided ($BOOST_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_BOOST)
-	AM_CONDITIONAL([BOOST],[test x$HAVE_BOOST = xyes])
-
-	dnl library and header files
-	if test "x$HAVE_BOOST" = "xyes"; then
-		BOOSTINCL=-I$BOOST_ROOT/include
-		BOOSTLIB="-L$BOOST_ROOT/lib -lboost_python"
-		AC_DEFINE([_HAVE_BOOST_],[1],[with Boost in ISSM src])
+		if ! test -d "${BOOST_ROOT}"; then
+			AC_MSG_ERROR([Boost directory provided (${BOOST_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_BOOST}])
+	AM_CONDITIONAL([BOOST], [test "x${HAVE_BOOST}" == "xyes"])
+
+	dnl Boost libraries and header files
+	if test "x${HAVE_BOOST}" == "xyes"; then
+		BOOSTINCL="-I${BOOST_ROOT}/include"
+		#BOOSTLIB="-L$BOOST_ROOT/lib -lboost_python"
+		AC_MSG_CHECKING(for Boost version)
+		BOOST_VERSION=`cat ${BOOST_ROOT}/include/boost/version.hpp | grep "#define BOOST_VERSION " | sed 's/.*BOOST_VERSION //'`
+		BOOST_VERSION_MAJOR=`expr ${BOOST_VERSION} / 100000`
+		BOOST_VERSION_MINOR=`expr ${BOOST_VERSION} / 100 % 1000`
+		AC_MSG_RESULT([${BOOST_VERSION_MAJOR}.${BOOST_VERSION_MINOR}])
+		AC_DEFINE([_HAVE_BOOST_], [1], [with Boost in ISSM src])
 		AC_SUBST([BOOSTINCL])
 		AC_SUBST([BOOSTLIB])
 	fi
 	dnl }}}
-	dnl dakota{{{
-	AC_ARG_WITH([dakota-dir],
-	  AS_HELP_STRING([--with-dakota-dir=DIR], [dakota root directory.]),
-	  [DAKOTA_ROOT=$withval],[DAKOTA_ROOT="no"])
-
-	dnl Check whether dakota is enabled
-	AC_MSG_CHECKING([for dakota])
-	if test "x$DAKOTA_ROOT" = "xno" ; then
+	dnl Dakota{{{
+	AC_ARG_WITH(
+		[dakota-dir],
+		AS_HELP_STRING([--with-dakota-dir=DIR], [Dakota root directory]),
+		[DAKOTA_ROOT=${withval}],
+		[DAKOTA_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for Dakota])
+	if test "x${DAKOTA_ROOT}" == "xno"; then
 		HAVE_DAKOTA=no
 	else
 		HAVE_DAKOTA=yes
-		if ! test -d "$DAKOTA_ROOT"; then
-			AC_MSG_ERROR([dakota directory provided ($DAKOTA_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_DAKOTA)
-	AM_CONDITIONAL([DAKOTA],[test x$HAVE_DAKOTA = xyes])
-
-	dnl library and header files
-	if test "x$HAVE_DAKOTA" = "xyes"; then
-		DAKOTAINCL=-I$DAKOTA_ROOT/include
-
-		AC_MSG_CHECKING(for dakota version)
-		if test -f "$DAKOTA_ROOT/VERSION"; then
-		 DAKOTA_VERSION=`cat $DAKOTA_ROOT/VERSION | grep 'DAKOTA Version' | sed 's/.*DAKOTA Version //' | sed 's/ .*//' `
-		else if test -f "$DAKOTA_ROOT/../src/src/CommandLineHandler.C"; then
-		 DAKOTA_VERSION=`cat $DAKOTA_ROOT/../src/src/CommandLineHandler.C | grep 'DAKOTA version' | grep 'release' | grep -v // | sed 's/.*DAKOTA version //' | sed 's/ .*//' `
-		else if test -f "$DAKOTA_ROOT/../src/src/CommandLineHandler.cpp"; then
-		 DAKOTA_VERSION=`cat $DAKOTA_ROOT/../src/src/CommandLineHandler.cpp | grep 'DAKOTA version' | grep 'release' | grep -v // | sed 's/.*DAKOTA version //' | sed 's/ .*//' `
+		if ! test -d "${DAKOTA_ROOT}"; then
+			AC_MSG_ERROR([Dakota directory provided (${DAKOTA_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_DAKOTA}])
+	AM_CONDITIONAL([DAKOTA], [test "x${HAVE_DAKOTA}" == "xyes"])
+
+	dnl Dakota libraries and header files
+	if test "x${HAVE_DAKOTA}" == "xyes"; then
+		DAKOTAINCL=-I${DAKOTA_ROOT}/include
+
+		AC_MSG_CHECKING(for Dakota version)
+		dnl TODO:	Check if this method applies to all other versions of
+		dnl 		(it should as long as the Dakota binaries have been
+		dnl 		compiled). If so, we can remove the other methods of
+		dnl 		getting the version.
+		dnl
+		DAKOTA_VERSION_OUTPUT=`${DAKOTA_ROOT}/bin/dakota -v`
+		if test -n "${DAKOTA_VERSION_OUTPUT}"; then
+			DAKOTA_VERSION=`echo ${DAKOTA_VERSION_OUTPUT} grep "Dakota version" | sed 's/Dakota version //' | sed 's/ .*//'`
+		elif test -f "${DAKOTA_ROOT}/VERSION"; then
+			DAKOTA_VERSION=`cat ${DAKOTA_ROOT}/VERSION | grep 'DAKOTA Version' | sed 's/.*DAKOTA Version //' | sed 's/ .*//'`
+		elif test -f "${DAKOTA_ROOT}/../src/src/CommandLineHandler.C"; then
+			DAKOTA_VERSION=`cat ${DAKOTA_ROOT}/../src/src/CommandLineHandler.C | grep 'DAKOTA version' | grep 'release' | grep -v // | sed 's/.*DAKOTA version //' | sed 's/ .*//' `
+		elif test -f "${DAKOTA_ROOT}/../src/src/CommandLineHandler.cpp"; then
+			DAKOTA_VERSION=`cat ${DAKOTA_ROOT}/../src/src/CommandLineHandler.cpp | grep 'DAKOTA version' | grep 'release' | grep -v // | sed 's/.*DAKOTA version //' | sed 's/ .*//' `
 		else
-		 AC_MSG_ERROR([Dakota CommandLineHandler.C or CommandLineHandler.cpp file not found to determine DAKOTA_VERSION!]);
-		fi
-		fi
-		fi
-		AC_MSG_RESULT($DAKOTA_VERSION)
-		AC_DEFINE_UNQUOTED([_DAKOTA_VERSION_],"$DAKOTA_VERSION",[Dakota version number])
+			AC_MSG_ERROR([Dakota CommandLineHandler.C or CommandLineHandler.cpp file not found to determine DAKOTA_VERSION!]);
+		fi
+		AC_MSG_RESULT([${DAKOTA_VERSION}])
+		AC_DEFINE_UNQUOTED(_DAKOTA_VERSION_, "${DAKOTA_VERSION}", [Dakota version number])
 
 		DAKOTAFLAGS=""
-		dnl TODO: Should we also be checking if HAVE_BOOST before adding boost libs?
+
+		dnl NOTE:
+		dnl - See $ISSM_DIR/dakota/build/src/Makefile.export.Dakota for the
+		dnl	  flags needed by your combination of Boost and Dakota versions
+		dnl - We know $DAKOTA_ROOT cannot be empty at this point, so no need to
+		dnl   check again in the following conditionals
+		dnl
+		dnl TODO:
+		dnl - Should we also be checking if HAVE_BOOST before adding boost libs?
+		dnl
 		case "${host_os}" in
 			*cygwin*)
-				if test x$DAKOTA_VERSION = x5.1 || test x$DAKOTA_VERSION = x5.2; then
-					DAKOTALIB="-L$DAKOTA_ROOT/lib -L$BOOST_ROOT/lib -ldakota -lteuchos -lpecos -llhs -lsparsegrid -lsurfpack -lconmin -lddace -lfsudace -ljega -lcport -loptpp -lpsuade -lncsuopt -lcolin -linterfaces -lmomh -lscolib -lpebbl -ltinyxml -lutilib -l3po -lhopspack -lnidr -lamplsolver -lboost_signals -lboost_regex -lboost_filesystem"
-				else if test x$DAKOTA_VERSION = x6.1 || test x$DAKOTA_VERSION = x6.2; then
-				   DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_COLINY -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_JEGA -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
-					DAKOTALIB="-L$DAKOTA_ROOT/lib -L$BOOST_ROOT/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -lscolib -ljega_fe -llhs -lpebbl -lcolin -linterfaces -llhs_mods -lmoga -loptpp -lsoga -lsurfpack -lutilib -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -l3po -lamplsolver -lcport -ldfftpack -leutils -lfsudace -lhopspack -ljega -lnidr -lpecos -lpsuade -ltinyxml -lutilities -lsparsegrid -lboost_serialization -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
-					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H],[1],[disabling DAKOTA_CONFIG_H])
-					AC_DEFINE([DAKOTA_HAVE_MPI],[1],[enabling parallel MPI])
+				if test "${DAKOTA_VERSION}" == "5.1" || test "${DAKOTA_VERSION}" == "5.2"; then
+					DAKOTALIB="-L${DAKOTA_ROOT}/lib -L${BOOST_ROOT}/lib -ldakota -lteuchos -lpecos -llhs -lsparsegrid -lsurfpack -lconmin -lddace -lfsudace -ljega -lcport -loptpp -lpsuade -lncsuopt -lcolin -linterfaces -lmomh -lscolib -lpebbl -ltinyxml -lutilib -l3po -lhopspack -lnidr -lamplsolver -lboost_signals -lboost_regex -lboost_filesystem"
+				elif test "${DAKOTA_VERSION}" == "6.1" || test "${DAKOTA_VERSION}" == "6.2"; then
+					DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_COLINY -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_JEGA -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+					DAKOTALIB="-L${DAKOTA_ROOT}/lib -L${BOOST_ROOT}/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -lscolib -ljega_fe -llhs -lpebbl -lcolin -linterfaces -llhs_mods -lmoga -loptpp -lsoga -lsurfpack -lutilib -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -l3po -lamplsolver -lcport -ldfftpack -leutils -lfsudace -lhopspack -ljega -lnidr -lpecos -lpsuade -ltinyxml -lutilities -lsparsegrid -lboost_serialization -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
+					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H], [1], [disabling DAKOTA_CONFIG_H])
+					AC_DEFINE([DAKOTA_HAVE_MPI], [1], [enabling parallel MPI])
 				else
-					AC_MSG_ERROR([Dakota version not found or version ($DAKOTA_VERSION) not supported!]);
+					AC_MSG_ERROR([Dakota version not found or version (${DAKOTA_VERSION}) not supported!]);
 				fi
+			;;
+			*darwin*)
+				if test "${DAKOTA_VERSION}" == "5.1" || test "${DAKOTA_VERSION}" == "5.2"; then
+					DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota -lteuchos -lpecos -llhs -lsparsegrid -lsurfpack -lconmin -lddace -lfsudace -ljega -lcport -loptpp -lpsuade -lncsuopt -lcolin -linterfaces -lmomh -lscolib -lpebbl -ltinyxml -lutilib -l3po -lhopspack -lnidr -lamplsolver -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
+				elif test "${DAKOTA_VERSION}" == "5.3" || test "${DAKOTA_VERSION}" == "5.3.1"; then
+					DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_COLINY -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_JEGA -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+					DAKOTALIB="-L${DAKOTA_ROOT}/lib -L${BOOST_ROOT}/lib -ldakota_src -lpecos_src -lscolib -ljega_fe -llhs -lpebbl -lcolin -linterfaces -lmods -lmoga -loptpp -lsampling -lsoga -lsurfpack -lutilib -lconmin -ldakota_src_fortran -lmod -lncsuopt -lsurfpack_fortran -lteuchos -l3po -lamplsolver -lanalyzer -lbose -lcport -ldace -ldfftpack -leutils -lfsudace -lhopspack -ljega -lnidr -lpecos -lpsuade -lrandom -ltinyxml -lutilities -lsparsegrid -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
+					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H], [1], [disabling DAKOTA_CONFIG_H])
+					AC_DEFINE([DAKOTA_HAVE_MPI], [1], [enabling parallel MPI])
+				elif test "${DAKOTA_VERSION}" == "6.1" || test "${DAKOTA_VERSION}" == "6.2"; then
+					DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+					if test "x${enable_standalone_executables}" == "xyes"; then
+						DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid ${BOOST_ROOT}/lib/libboost_serialization.a ${BOOST_ROOT}/lib/libboost_signals.a ${BOOST_ROOT}/lib/libboost_regex.a ${BOOST_ROOT}/lib/libboost_filesystem.a ${BOOST_ROOT}/lib/libboost_system.a"
+					else
+						DAKOTALIB="-L${DAKOTA_ROOT}/lib -L${BOOST_ROOT}/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid -lboost_serialization -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
+					fi
+					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H], [1], [disabling DAKOTA_CONFIG_H])
+					AC_DEFINE([DAKOTA_HAVE_MPI], [1], [enabling Dakota with MPI])
+				elif test "${DAKOTA_VERSION}" == "6.11"; then
+					DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+					dnl See $ISSM_DIR/dakota/build/src/Makefile.export.Dakota -> Dakota_LIBRARIES
+					DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota_src -ldakota_src_fortran -lnidr -lteuchosremainder -lteuchosnumerics -lteuchoscomm -lteuchosparameterlist -lteuchosparser -lteuchoscore -lpecos_util -lpecos_src -llhs -llhs_mods -llhs_mod -ldfftpack -lsparsegrid -lsurfpack -lsurfpack -lsurfpack_fortran -lapproxnn -lconmin -lddace -ldream -lfsudace -lhopspack -lncsuopt -lcport -lnomad -loptpp -lpsuade -lamplsolver -L${BOOST_ROOT}/lib -lboost_serialization -lboost_regex -lboost_filesystem -lboost_system"
+					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H], [1], [disabling DAKOTA_CONFIG_H])
+					AC_DEFINE([DAKOTA_HAVE_MPI], [1], [enabling Dakota with MPI])
+				else
+					AC_MSG_ERROR([Dakota version not found or version (${DAKOTA_VERSION}) not supported!]);
 				fi
 			;;
 			*linux*)
-				if test x$DAKOTA_VERSION = x5.1 || test x$DAKOTA_VERSION = x5.2; then
-					DAKOTALIB="-L$DAKOTA_ROOT/lib -ldakota -lteuchos -lpecos -llhs -lsparsegrid -lsurfpack -lconmin -lddace -lfsudace -ljega -lcport -loptpp -lpsuade -lncsuopt -lcolin -linterfaces -lmomh -lscolib -lpebbl -ltinyxml -lutilib -l3po -lhopspack -lnidr -lamplsolver -lboost_signals -lboost_regex -lboost_filesystem -lboost_system -ldl"
-				else if test x$DAKOTA_VERSION = x5.3 || test x$DAKOTA_VERSION = x5.3.1; then
+				if test "${DAKOTA_VERSION}" == "5.1" || test "${DAKOTA_VERSION}" == "5.2"; then
+					DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota -lteuchos -lpecos -llhs -lsparsegrid -lsurfpack -lconmin -lddace -lfsudace -ljega -lcport -loptpp -lpsuade -lncsuopt -lcolin -linterfaces -lmomh -lscolib -lpebbl -ltinyxml -lutilib -l3po -lhopspack -lnidr -lamplsolver -lboost_signals -lboost_regex -lboost_filesystem -lboost_system -ldl"
+				elif test "${DAKOTA_VERSION}" == "5.3" || test "${DAKOTA_VERSION}" == "5.3.1"; then
 					DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_COLINY -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_JEGA -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
-					DAKOTALIB="-L$DAKOTA_ROOT/lib -L$BOOST_ROOT/lib -ldakota_src -lpecos_src -lscolib -ljega_fe -llhs -lpebbl -lcolin -linterfaces -lmods -lmoga -loptpp -lsampling -lsoga -lsurfpack -lutilib -lconmin -ldakota_src_fortran -lmod -lncsuopt -lsurfpack_fortran -lteuchos -l3po -lamplsolver -lanalyzer -lbose -lcport -ldace -ldfftpack -leutils -lfsudace -lhopspack -ljega -lnidr -lpecos -lpsuade -lrandom -ltinyxml -lutilities -lsparsegrid -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
-					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H],[1],[disabling DAKOTA_CONFIG_H])
-					AC_DEFINE([DAKOTA_HAVE_MPI],[1],[enabling parallel MPI])
-				else if test x$DAKOTA_VERSION = x6.1 || test x$DAKOTA_VERSION = x6.2; then
-				   DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
-					if test "x$enable_standalone_executables" = "xyes"; then
-						DAKOTALIB="-L$DAKOTA_ROOT/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid $BOOST_ROOT/lib/libboost_serialization.a $BOOST_ROOT/lib/libboost_signals.a $BOOST_ROOT/lib/libboost_regex.a $BOOST_ROOT/lib/libboost_filesystem.a $BOOST_ROOT/lib/libboost_system.a"
-					else
-						DAKOTALIB="-L$DAKOTA_ROOT/lib -L$BOOST_ROOT/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid -lboost_serialization -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
+					DAKOTALIB="-L${DAKOTA_ROOT}/lib -L${BOOST_ROOT}/lib -ldakota_src -lpecos_src -lscolib -ljega_fe -llhs -lpebbl -lcolin -linterfaces -lmods -lmoga -loptpp -lsampling -lsoga -lsurfpack -lutilib -lconmin -ldakota_src_fortran -lmod -lncsuopt -lsurfpack_fortran -lteuchos -l3po -lamplsolver -lanalyzer -lbose -lcport -ldace -ldfftpack -leutils -lfsudace -lhopspack -ljega -lnidr -lpecos -lpsuade -lrandom -ltinyxml -lutilities -lsparsegrid -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
+					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H], [1], [disabling DAKOTA_CONFIG_H])
+					AC_DEFINE([DAKOTA_HAVE_MPI], [1], [enabling Dakota with MPI])
+				elif test "${DAKOTA_VERSION}" == "6.1" || test "${DAKOTA_VERSION}" == "6.2"; then
+					if test "${BOOST_VERSION_MAJOR}" == "1"; then
+						if test "${BOOST_VERSION_MINOR}" == "55"; then
+							DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+							DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid -L$BOOST_ROOT/lib -lboost_serialization -lboost_signals -lboost_regex -lboost_filesystem -lboost_system -L${BLASLAPACK_ROOT}/lib -llapack -lblas"
+						elif test "${BOOST_VERSION_MINOR}" = "72"; then
+							DAKOTAFLAGS="-DHAVE_CONFIG_H -DHAVE_CONFIG_H -DDISABLE_DAKOTA_CONFIG_H -DBOOST_DISABLE_ASSERTS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DHAVE_ADAPTIVE_SAMPLING -DHAVE_ESM -DHAVE_CONMIN -DHAVE_DDACE -DHAVE_DREAM -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_NOMAD -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+							dnl See $ISSM_DIR/dakota/build/src/Makefile.export.Dakota -> Dakota_LIBRARIES
+							DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota_src -ldakota_src_fortran -lnidr -lteuchos -lpecos -lpecos_src -llhs -llhs_mods -llhs_mod -ldfftpack -lsparsegrid -lsurfpack -lsurfpack -lsurfpack_fortran -lconmin -lddace -ldream -lfsudace -lhopspack -lncsuopt -lcport -lnomad -loptpp -lpsuade -lamplsolver -L${BOOST_ROOT}/lib -lboost_filesystem -lboost_program_options -lboost_regex -lboost_serialization -lboost_system -L${BLASLAPACK_ROOT}/lib -llapack -lblas"
+						fi
 					fi
-					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H],[1],[disabling DAKOTA_CONFIG_H])
-					AC_DEFINE([DAKOTA_HAVE_MPI],[1],[enabling parallel MPI])
+					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H], [1], [disabling DAKOTA_CONFIG_H])
+					AC_DEFINE([DAKOTA_HAVE_MPI], [1], [enabling Dakota with MPI])
+				elif test "${DAKOTA_VERSION}" == "6.11"; then
+					if test "${BOOST_VERSION_MAJOR}" == "1"; then
+						if test "${BOOST_VERSION_MINOR}" == "55"; then
+							DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+							DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid -L$BOOST_ROOT/lib -lboost_serialization -lboost_signals -lboost_regex -lboost_filesystem -lboost_system -L${BLASLAPACK_ROOT}/lib -llapack -lblas"
+						elif test "${BOOST_VERSION_MINOR}" == "72"; then
+							DAKOTAFLAGS="-DHAVE_CONFIG_H -DHAVE_CONFIG_H -DDISABLE_DAKOTA_CONFIG_H -DBOOST_DISABLE_ASSERTS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DHAVE_ADAPTIVE_SAMPLING -DHAVE_ESM -DHAVE_CONMIN -DHAVE_DDACE -DHAVE_DREAM -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_NOMAD -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
+							DAKOTALIB="-L${DAKOTA_ROOT}/lib -ldakota_src -ldakota_src_fortran -lnidr -lteuchosremainder -lteuchosnumerics -lteuchoscomm -lteuchosparameterlist -lteuchosparser -lteuchoscore -lpecos_util -lpecos_src -llhs -llhs_mods -llhs_mod -ldfftpack -lsparsegrid -lsurfpack -lsurfpack -lsurfpack_fortran -lapproxnn -lconmin -lddace -ldream -lfsudace -lhopspack -lncsuopt -lcport -lnomad -loptpp -lpsuade -lamplsolver -L${BOOST_ROOT}/lib -lboost_filesystem -lboost_program_options -lboost_regex -lboost_serialization -lboost_system -L${BLASLAPACK_ROOT}/lib -llapack -lblas"
+						fi
+					fi
+					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H], [1], [disabling DAKOTA_CONFIG_H])
+					AC_DEFINE([DAKOTA_HAVE_MPI], [1], [enabling Dakota with MPI])
 				else
-					AC_MSG_ERROR([Dakota version not found or version ($DAKOTA_VERSION) not supported!]);
+					AC_MSG_ERROR([Dakota version not found or version (${DAKOTA_VERSION}) not supported!]);
 				fi
-				fi
-				fi
-			;;
-			*darwin*)
-				if test x$DAKOTA_VERSION = x5.1 || test x$DAKOTA_VERSION = x5.2; then
-					DAKOTALIB="-L$DAKOTA_ROOT/lib -ldakota -lteuchos -lpecos -llhs -lsparsegrid -lsurfpack -lconmin -lddace -lfsudace -ljega -lcport -loptpp -lpsuade -lncsuopt -lcolin -linterfaces -lmomh -lscolib -lpebbl -ltinyxml -lutilib -l3po -lhopspack -lnidr -lamplsolver -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
-				else if test x$DAKOTA_VERSION = x5.3 || test x$DAKOTA_VERSION = x5.3.1; then
-					DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_COLINY -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_JEGA -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
-					DAKOTALIB="-L$DAKOTA_ROOT/lib -L$BOOST_ROOT/lib -ldakota_src -lpecos_src -lscolib -ljega_fe -llhs -lpebbl -lcolin -linterfaces -lmods -lmoga -loptpp -lsampling -lsoga -lsurfpack -lutilib -lconmin -ldakota_src_fortran -lmod -lncsuopt -lsurfpack_fortran -lteuchos -l3po -lamplsolver -lanalyzer -lbose -lcport -ldace -ldfftpack -leutils -lfsudace -lhopspack -ljega -lnidr -lpecos -lpsuade -lrandom -ltinyxml -lutilities -lsparsegrid -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
-					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H],[1],[disabling DAKOTA_CONFIG_H])
-					AC_DEFINE([DAKOTA_HAVE_MPI],[1],[enabling parallel MPI])
-				else if test x$DAKOTA_VERSION = x6.1 || test x$DAKOTA_VERSION = x6.2; then
-					DAKOTAFLAGS="-DDISABLE_DAKOTA_CONFIG_H -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DDAKOTA_PLUGIN -DBOOST_DISABLE_ASSERTS -DDAKOTA_HAVE_BOOST_FS -DHAVE_UNISTD_H -DHAVE_SYSTEM -DHAVE_WORKING_FORK -DHAVE_WORKING_VFORK -DHAVE_SYS_WAIT_H -DHAVE_USLEEP -DDAKOTA_F90 -DDAKOTA_HAVE_MPI -DHAVE_PECOS -DHAVE_SURFPACK -DDAKOTA_UTILIB -DHAVE_ADAPTIVE_SAMPLING -DHAVE_CONMIN -DDAKOTA_DDACE -DHAVE_FSUDACE -DDAKOTA_HOPS -DHAVE_NCSU -DHAVE_NL2SOL -DHAVE_OPTPP -DDAKOTA_OPTPP -DHAVE_PSUADE -DHAVE_AMPL"
-					if test "x$enable_standalone_executables" = "xyes"; then
-						DAKOTALIB="-L$DAKOTA_ROOT/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid $BOOST_ROOT/lib/libboost_serialization.a $BOOST_ROOT/lib/libboost_signals.a $BOOST_ROOT/lib/libboost_regex.a $BOOST_ROOT/lib/libboost_filesystem.a $BOOST_ROOT/lib/libboost_system.a"
-					else
-						DAKOTALIB="-L$DAKOTA_ROOT/lib -L$BOOST_ROOT/lib -ldakota_src -ldream -lfsudace -lddace -lnomad -lpecos_src -llhs -llhs_mods -loptpp -lsurfpack -lconmin -ldakota_src_fortran -llhs_mod -lncsuopt -lsurfpack_fortran -lteuchos -lamplsolver -lcport -ldfftpack -lfsudace -lhopspack -lnidr -lpecos -lpsuade -lsparsegrid -lboost_serialization -lboost_signals -lboost_regex -lboost_filesystem -lboost_system"
-					fi
-					AC_DEFINE([DISABLE_DAKOTA_CONFIG_H],[1],[disabling DAKOTA_CONFIG_H])
-					AC_DEFINE([DAKOTA_HAVE_MPI],[1],[enabling parallel MPI])
-				else
-					AC_MSG_ERROR([Dakota version not found or version ($DAKOTA_VERSION) not supported!]);
-				fi
-				fi
-				fi
 			;;
 		esac
 
-		case $DAKOTA_VERSION in
-			@<:@1-9@:>@.@<:@0-9@:>@.@<:@0-9@:>@)
-				DAKOTA_MAJOR=`echo $DAKOTA_VERSION | sed -e 's/^\(@<:@0-9@:>@*\)\..*/\1/'`
-				DAKOTA_MINOR=`echo $DAKOTA_VERSION | sed -e 's/^@<:@0-9@:>@*\.\(@<:@0-9@:>@*\)\..*/\1/'`
-				DAKOTA_BUILD=`echo $DAKOTA_VERSION | sed -e 's/^@<:@0-9@:>@*\.@<:@0-9@:>@*\.\(@<:@0-9@:>@*\).*/\1/'`
-			;;
-			@<:@1-9@:>@.@<:@0-9@:>@)
-				DAKOTA_MAJOR=`echo $DAKOTA_VERSION | sed -e 's/^\(@<:@0-9@:>@*\)\..*/\1/'`
-				DAKOTA_MINOR=`echo $DAKOTA_VERSION | sed -e 's/^@<:@0-9@:>@*\.\(@<:@0-9@:>@*\).*/\1/'`
+		case ${DAKOTA_VERSION} in
+			@<:@1-9@:>@*.@<:@0-9@:>@*.@<:@0-9@:>@*)
+				DAKOTA_MAJOR=`echo ${DAKOTA_VERSION} | sed -e 's/^\(@<:@0-9@:>@*\)\..*/\1/'`
+				DAKOTA_MINOR=`echo ${DAKOTA_VERSION} | sed -e 's/^@<:@0-9@:>@*\.\(@<:@0-9@:>@*\)\..*/\1/'`
+				DAKOTA_BUILD=`echo ${DAKOTA_VERSION} | sed -e 's/^@<:@0-9@:>@*\.@<:@0-9@:>@*\.\(@<:@0-9@:>@*\).*/\1/'`
+			;;
+			@<:@1-9@:>@*.@<:@0-9@:>@*)
+				DAKOTA_MAJOR=`echo ${DAKOTA_VERSION} | sed -e 's/^\(@<:@0-9@:>@*\)\..*/\1/'`
+				DAKOTA_MINOR=`echo ${DAKOTA_VERSION} | sed -e 's/^@<:@0-9@:>@*\.\(@<:@0-9@:>@*\).*/\1/'`
 				DAKOTA_BUILD=0
 			;;
-			@<:@1-9@:>@.@<:@0-9@:>@+)
-				DAKOTA_MAJOR=`echo $DAKOTA_VERSION | sed -e 's/^\(@<:@0-9@:>@*\)\..*/\1/'`
-				DAKOTA_MINOR=`echo $DAKOTA_VERSION | sed -e 's/^@<:@0-9@:>@*\.\(@<:@0-9@:>@*\).*/\1/'`
-				DAKOTA_BUILD=0
-			;;
 			*)
-				AC_MSG_ERROR([Dakota version ($DAKOTA_VERSION) not supported!]);
-		   ;;
+				AC_MSG_ERROR([Dakota version (${DAKOTA_VERSION}) not supported!])
+			;;
 		esac
-		AC_MSG_CHECKING(for dakota major version)
-		AC_MSG_RESULT($DAKOTA_MAJOR)
-		AC_DEFINE_UNQUOTED([_DAKOTA_MAJOR_],$DAKOTA_MAJOR,[Dakota major version number])
-		AC_MSG_CHECKING(for dakota minor version)
-		AC_MSG_RESULT($DAKOTA_MINOR)
-		AC_DEFINE_UNQUOTED([_DAKOTA_MINOR_],$DAKOTA_MINOR,[Dakota minor version number])
+		AC_MSG_CHECKING(for Dakota major version)
+		AC_MSG_RESULT(${DAKOTA_MAJOR})
+		AC_DEFINE_UNQUOTED(_DAKOTA_MAJOR_, $DAKOTA_MAJOR, [Dakota major version number])
+		AC_MSG_CHECKING(for Dakota minor version)
+		AC_MSG_RESULT(${DAKOTA_MINOR})
+		AC_DEFINE_UNQUOTED(_DAKOTA_MINOR_, $DAKOTA_MINOR, [Dakota minor version number])
 		AC_MSG_CHECKING(for dakota build version)
-		AC_MSG_RESULT($DAKOTA_BUILD)
-		AC_DEFINE_UNQUOTED([_DAKOTA_BUILD_],$DAKOTA_BUILD,[Dakota build version number])
-
-		AC_DEFINE([_HAVE_DAKOTA_],[1],[with Dakota in ISSM src])
+		AC_MSG_RESULT(${DAKOTA_BUILD})
+		AC_DEFINE_UNQUOTED(_DAKOTA_BUILD_, $DAKOTA_BUILD, [Dakota build version number])
+
+		AC_DEFINE([_HAVE_DAKOTA_], [1], [with Dakota in ISSM src])
 		AC_SUBST([DAKOTAINCL])
 		AC_SUBST([DAKOTAFLAGS])
 		AC_SUBST([DAKOTALIB])
 	fi
-	AM_CONDITIONAL([ISSM_DAKOTA],[test x$DAKOTA_MAJOR = x6])
-	dnl }}}
-	dnl python{{{
-	AC_ARG_WITH([python-dir],
-	  AS_HELP_STRING([--with-python-dir=DIR], [python root directory.]),
-	  [PYTHON_ROOT=$withval],[PYTHON_ROOT="no"])
-
-	AC_ARG_WITH([python-version],
-	  AS_HELP_STRING([--with-python-version=DIR], [python forced version.]),
-	  [PYTHON_VERSION=$withval],[PYTHON_VERSION="no"])
-
-	dnl Check whether python is enabled
-	AC_MSG_CHECKING([for python])
-	if test "x$PYTHON_ROOT" = "xno" ; then
+	AM_CONDITIONAL([ISSM_DAKOTA], [test "x${DAKOTA_MAJOR}" == "x6"])
+	dnl }}}
+	dnl Python{{{
+	AC_ARG_WITH(
+		[python-dir],
+		AS_HELP_STRING([--with-python-dir=DIR], [Python root directory]),
+		[PYTHON_ROOT=${withval}],
+		[PYTHON_ROOT="no"]
+	)
+
+	AC_ARG_WITH(
+		[python-version],
+		AS_HELP_STRING([--with-python-version=DIR], [Python forced version]),
+		[PYTHON_VERSION=${withval}],
+		[PYTHON_VERSION="no"]
+	)
+	AC_MSG_CHECKING([for Python])
+	if test "x${PYTHON_ROOT}" == "xno"; then
 		HAVE_PYTHON=no
 		HAVE_PYTHON3=no
 	else
 		HAVE_PYTHON=yes
-		if ! test -d "$PYTHON_ROOT"; then
-			AC_MSG_ERROR([python directory provided ($PYTHON_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_PYTHON)
-	AM_CONDITIONAL([PYTHON],[test x$HAVE_PYTHON = xyes])
-
-	dnl python specifics
-	if test "x$HAVE_PYTHON" = "xyes"; then
-		if test "x$PYTHON_VERSION" = "xno" ; then
-			AC_MSG_CHECKING([for python version])
-			dnl Query Python for its version number. Getting [:3] seems to be the
-			dnl best way to do this; it's what "site.py" does in the standard library.
-			PYTHON_VERSION=$($PYTHON_ROOT/bin/python -c "import sys; print sys.version[[:3]]")
-			AC_MSG_RESULT($PYTHON_VERSION)
+		if ! test -d "${PYTHON_ROOT}"; then
+			AC_MSG_ERROR([Python directory provided (${PYTHON_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_PYTHON}])
+	AM_CONDITIONAL([PYTHON], [test "x${HAVE_PYTHON}" == "xyes"])
+
+	dnl Python specifics
+	if test "x${HAVE_PYTHON}" == "xyes"; then
+		if test "x${PYTHON_VERSION}" == "xno"; then
+			AC_MSG_CHECKING([for Python version])
+			dnl Query Python for its version number. Getting [:3] seems to be
+			dnl the best way to do this: it's what "site.py" does in the
+			dnl standard library.
+			PYTHON_VERSION=$(${PYTHON_ROOT}/bin/python -c "import sys; print sys.version[[:3]]")
+			AC_MSG_RESULT([${PYTHON_VERSION}])
 		else
-			AC_MSG_RESULT([enforced  python version is ]$PYTHON_VERSION)
-		fi
-		dnl recover major
+			AC_MSG_RESULT([enforced Python version is ${PYTHON_VERSION}])
+		fi
+		dnl Determine major version
 		PYTHON_MAJOR=${PYTHON_VERSION%.*}
-		AC_DEFINE_UNQUOTED([_PYTHON_MAJOR_],$PYTHON_MAJOR,[python version major])
-		if test "x$PYTHON_MAJOR" = "x3"; then
+		AC_DEFINE_UNQUOTED(_PYTHON_MAJOR_, $PYTHON_MAJOR, [Python version major])
+		if test "x${PYTHON_MAJOR}" == "x3"; then
 			HAVE_PYTHON3="yes"
 		else
@@ -636,629 +691,657 @@
 		fi
 
-		AC_MSG_CHECKING([for python header file Python.h])
-		dnl Python.h mighty be in different locations:
-		if test -f "$PYTHON_ROOT/include/Python.h"; then
-			PYTHONINCL=-I$PYTHON_ROOT/include
-		else if test -f "$PYTHON_ROOT/include/python$PYTHON_VERSION/Python.h"; then
-			PYTHONINCL=-I$PYTHON_ROOT/include/python$PYTHON_VERSION
-		else if test -f "$PYTHON_ROOT/include/python$PYTHON_VERSIONm/Python.h"; then
-			PYTHONINCL=-I$PYTHON_ROOT/include/python$PYTHON_VERSIONm
+		AC_MSG_CHECKING([for Python header file Python.h])
+		dnl Python.h might be in different locations:
+		if test -f "${PYTHON_ROOT}/include/Python.h"; then
+			PYTHONINCL=-I${PYTHON_ROOT}/include
+		elif test -f "${PYTHON_ROOT}/include/python${PYTHON_VERSION}/Python.h"; then
+			PYTHONINCL=-I${PYTHON_ROOT}/include/python${PYTHON_VERSION}
+		elif test -f "${PYTHON_ROOT}/include/python${PYTHON_VERSION}m/Python.h"; then
+			PYTHONINCL=-I${PYTHON_ROOT}/include/python${PYTHON_VERSION}m
 		else
 			AC_MSG_ERROR([Python.h not found, locate this file and contact ISSM developers]);
 		fi
-		fi
-		fi
-		AC_MSG_RESULT(found)
-		if test "x$PYTHON_MAJOR" = "x3"; then
-				PYTHONLIB="-L$PYTHON_ROOT/lib -lpython$PYTHON_VERSION""m"
+		AC_MSG_RESULT([found])
+		if test "x${PYTHON_MAJOR}" == "x3"; then
+			PYTHONLIB="-L${PYTHON_ROOT}/lib -lpython${PYTHON_VERSION}m"
 		else
-				PYTHONLIB="-L$PYTHON_ROOT/lib -lpython$PYTHON_VERSION"
+			PYTHONLIB="-L${PYTHON_ROOT}/lib -lpython${PYTHON_VERSION}"
 		fi
 		PYTHONEXT=.so
 		case "${host_os}" in
 			*cygwin*)
-			PYTHONLINK="-shared"
+				PYTHONLINK="-shared"
 			;;
 			*linux*)
-			PYTHONLINK="-shared"
+				PYTHONLINK="-shared"
 			;;
 			*darwin*)
-			PYTHONLINK="-dynamiclib"
+				PYTHONLINK="-dynamiclib"
 			;;
 		esac
-		AC_DEFINE([_HAVE_PYTHON_],[1],[with python in ISSM src])
+		AC_DEFINE([_HAVE_PYTHON_], [1], [with Python in ISSM src])
 		AC_SUBST([PYTHONINCL])
 		AC_SUBST([PYTHONLIB])
-		PYTHONWRAPPEREXT=$PYTHONEXT
+		PYTHONWRAPPEREXT=${PYTHONEXT}
 		AC_SUBST([PYTHONWRAPPEREXT])
 		AC_SUBST([PYTHONLINK])
 	fi
-	AM_CONDITIONAL([PYTHON3], [test x$HAVE_PYTHON3 = xyes])
-	dnl }}}
-	dnl python-numpy{{{
-	AC_ARG_WITH([python-numpy-dir],
-	  AS_HELP_STRING([--with-python-numpy-dir=DIR], [python-numpy root directory.]),
-	  [PYTHON_NUMPY_ROOT=$withval],[PYTHON_NUMPY_ROOT="no"])
-
-	dnl you can find numpy by typing
-	dnl >>> import numpy
-	dnl >>> numpy.__file__
-	dnl '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/__init__.pyc'
-
-	dnl Check whether numpy is enabled
+	AM_CONDITIONAL([PYTHON3], [test "x${HAVE_PYTHON3}" == "xyes"])
+	dnl }}}
+	dnl NumPy{{{
+	dnl TODO:
+	dnl - Replace references to python-numpy with numpy (and similar terms)
+	dnl	  project-wide
+	dnl
+	AC_ARG_WITH(
+		[python-numpy-dir],
+		AS_HELP_STRING([--with-python-numpy-dir=DIR], [python-numpy root directory]),
+		[PYTHON_NUMPY_ROOT=${withval}],
+		[PYTHON_NUMPY_ROOT="no"]
+	)
+
+	dnl NOTE: You can find NumPy by running,
+	dnl
+	dnl		>>> import numpy
+	dnl		>>> numpy.__file__
+	dnl
+
 	AC_MSG_CHECKING(for python-numpy)
-	if test "x$PYTHON_NUMPY_ROOT" = "xno" ; then
+	if test "x${PYTHON_NUMPY_ROOT}" == "xno"; then
 		HAVE_PYTHON_NUMPY=no
 	else
 		HAVE_PYTHON_NUMPY=yes
-		if ! test -d "$PYTHON_NUMPY_ROOT"; then
-			AC_MSG_ERROR([numpy directory provided ($PYTHON_NUMPY_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_PYTHON_NUMPY)
-
-	dnl numpy lib
-	if test "x$HAVE_PYTHON_NUMPY" = "xyes"; then
-		PYTHON_NUMPYINCL="-I$PYTHON_NUMPY_ROOT -I$PYTHON_NUMPY_ROOT/core/include/numpy"
-		AC_DEFINE([_HAVE_PYTHON_NUMPY_],[1],[with Python-Numpy in ISSM src])
+		if ! test -d "${PYTHON_NUMPY_ROOT}"; then
+			AC_MSG_ERROR([NumPy directory provided (${PYTHON_NUMPY_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_PYTHON_NUMPY}])
+
+	dnl NumPy libraries and header files
+	if test "x${HAVE_PYTHON_NUMPY}" == "xyes"; then
+		PYTHON_NUMPYINCL="-I${PYTHON_NUMPY_ROOT} -I${PYTHON_NUMPY_ROOT}/core/include/numpy"
+		AC_DEFINE([_HAVE_PYTHON_NUMPY_], [1], [with NumPy in ISSM src])
 		AC_SUBST([PYTHON_NUMPYINCL])
 	fi
 	dnl }}}
-	dnl chaco{{{
-	AC_ARG_WITH([chaco-dir],
-	  AS_HELP_STRING([--with-chaco-dir=DIR], [chaco root directory.]),
-	  [CHACO_ROOT=$withval],[CHACO_ROOT="no"])
-
-	dnl Check whether chaco is enabled
-	AC_MSG_CHECKING([for chaco])
-	if test "x$CHACO_ROOT" = "xno" ; then
+	dnl Chaco{{{
+	AC_ARG_WITH(
+		[chaco-dir],
+		AS_HELP_STRING([--with-chaco-dir=DIR], [Chaco root directory]),
+		[CHACO_ROOT=${withval}],
+		[CHACO_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for Chaco])
+	if test "x${CHACO_ROOT}" == "xno"; then
 		HAVE_CHACO=no
 	else
 		HAVE_CHACO=yes
-		if ! test -d "$CHACO_ROOT"; then
-			AC_MSG_ERROR([chaco directory provided ($CHACO_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_CHACO)
-	AM_CONDITIONAL([CHACO],[test x$HAVE_CHACO = xyes])
-
-	dnl library and header files
-	if test "x$HAVE_CHACO" = "xyes"; then
-		CHACOINCL=-I$CHACO_ROOT/include
-		CHACOLIB="-L$CHACO_ROOT/lib -lchacominusblas"
-		AC_DEFINE([_HAVE_CHACO_],[1],[with Chaco in ISSM src])
+		if ! test -d "${CHACO_ROOT}"; then
+			AC_MSG_ERROR([Chaco directory provided (${CHACO_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_CHACO}])
+	AM_CONDITIONAL([CHACO], [test "x${HAVE_CHACO}" == "xyes"])
+
+	dnl Chaco libraries and header files
+	if test "x${HAVE_CHACO}" == "xyes"; then
+		CHACOINCL=-I${CHACO_ROOT}/include
+		CHACOLIB="-L${CHACO_ROOT}/lib -lchacominusblas"
+		AC_DEFINE([_HAVE_CHACO_], [1], [with Chaco in ISSM src])
 		AC_SUBST([CHACOINCL])
 		AC_SUBST([CHACOLIB])
 	fi
 	dnl }}}
-	dnl scotch{{{
-	AC_ARG_WITH([scotch-dir],
-	  AS_HELP_STRING([--with-scotch-dir=DIR], [scotch root directory.]),
-	  [SCOTCH_ROOT=$withval],[SCOTCH_ROOT="no"])
-
-  dnl Check whether scotch is enabled
-	AC_MSG_CHECKING([for scotch])
-	if test "x$SCOTCH_ROOT" = "xno" ; then
+	dnl ESMF{{{
+	AC_ARG_WITH(
+		[esmf-dir],
+		AS_HELP_STRING([--with-esmf-dir=DIR], [ESMF root directory]),
+		[ESMF_ROOT=${withval}],
+		[ESMF_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for ESMF])
+	if test "x${ESMF_ROOT}" == "xno"; then
+		HAVE_ESMF=no
+	else
+		HAVE_ESMF=yes
+		if ! test -d "${ESMF_ROOT}"; then
+			AC_MSG_ERROR([ESMF directory provided (${ESMF_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_ESMF}])
+
+	dnl ESMF libraries and header files
+	if test "x${HAVE_ESMF}" == "xyes"; then
+		ESMFINCL="-I${ESMF_ROOT}/include"
+		ESMFLIB="-L${ESMF_ROOT}/lib -lesmf"
+		AC_DEFINE([_HAVE_ESMF_], [1], [with ESMF in ISSM src])
+		AC_SUBST([ESMFINCL])
+		AC_SUBST([ESMFLIB])
+	fi
+	AM_CONDITIONAL([ESMF], [test "x${HAVE_ESMF}" == "xyes"])
+	dnl }}}
+	dnl CoDiPack{{{
+	AC_ARG_WITH(
+		[codipack-dir],
+		AS_HELP_STRING([--with-codipack-dir=DIR], [CoDiPack root directory]),
+		[CODIPACK_ROOT=${withval}],
+		[CODIPACK_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for CoDiPack])
+	if test "x${CODIPACK_ROOT}" == "xno"; then
+		HAVE_CODIPACK=no
+	else
+		HAVE_CODIPACK=yes
+		if ! test -d "${CODIPACK_ROOT}"; then
+			AC_MSG_ERROR([CoDiPack directory provided (${CODIPACK_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_CODIPACK}])
+
+	dnl CoDiPack libraries and header files
+	if test "x${HAVE_CODIPACK}" == "xyes"; then
+		CODIPACKINCL="-I${CODIPACK_ROOT}/include"
+		AC_DEFINE([_HAVE_CODIPACK_], [1], [with CoDiPack in ISSM src])
+		AC_DEFINE([_HAVE_AD_], [1], [with AD in ISSM src])
+		AC_SUBST([CODIPACKINCL])
+	fi
+	AM_CONDITIONAL([CODIPACK], [test "x${HAVE_CODIPACK}" == "xyes"])
+	AM_COND_IF(CODIPACK, [CXXFLAGS+=" -std=c++11"])
+	dnl }}}
+	dnl Tape Allocation {{{
+	AC_ARG_ENABLE(
+		[tape-alloc],																dnl feature
+		AS_HELP_STRING([--enable-tape-alloc], [turn tape allocation support on]),
+		[enable_tape_alloc=${enableval}],
+		[enable_tape_alloc=no]
+	)
+	AC_MSG_CHECKING(for tape allocation)
+	if test "x${enable_tape_alloc}" == "xyes"; then
+		AC_DEFINE([_AD_TAPE_ALLOC_], [1], [enable a priori tape allocation for AD])
+	fi
+	AC_MSG_RESULT([${enable_tape_alloc}])
+	dnl }}}
+	dnl ADOL-C {{{
+	AC_ARG_WITH(
+		[adolc-dir],
+		AS_HELP_STRING([--with-adolc-dir=DIR], [ADOL-C root directory]),
+		[ADOLC_ROOT=${withval}],
+		[ADOLC_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for ADOL-C])
+	if test "x${ADOLC_ROOT}" == "xno"; then
+		HAVE_ADOLC=no
+	else
+		HAVE_ADOLC=yes
+		if ! test -d "${ADOLC_ROOT}"; then
+			AC_MSG_ERROR([ADOL-C directory provided (${ADOLC_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_ADOLC}])
+
+	dnl ADOL-C libraries and header files
+	if test "x${HAVE_ADOLC}" == "xyes"; then
+		ADOLCINCL="-I${ADOLC_ROOT}/include"
+		dnl ADOLCLIB="-L${ADOLC_ROOT}/lib64 -ladolc" used to be the path
+		ADOLCLIB="-L${ADOLC_ROOT}/lib -ladolc"
+		AC_DEFINE([_HAVE_ADOLC_], [1], [with ADOL-C in ISSM src])
+		AC_DEFINE([_HAVE_AD_], [1], [with AD in ISSM src])
+		AC_SUBST([ADOLCINCL])
+		AC_SUBST([ADOLCLIB])
+	fi
+	AM_CONDITIONAL([ADOLC], [test "x${HAVE_ADOLC}" == "xyes"])
+	AM_COND_IF(ADOLC, [CXXFLAGS+=" -std=c++11"])
+	dnl }}}
+	dnl ADOL-C version{{{
+	AC_ARG_WITH(
+		[adolc-version],
+		AS_HELP_STRING([--with-adolc-version=number], [ADOL-C version]),
+		[ADOLC_VERSION=${withval}],
+		[ADOLC_VERSION=2]
+	)
+	AC_MSG_CHECKING(for ADOL-C version)
+
+	AC_DEFINE_UNQUOTED(_ADOLC_VERSION_, $ADOLC_VERSION, [ADOL-C version])
+	AC_MSG_RESULT(${ADOLC_VERSION})
+	dnl }}}
+	dnl ADIC2 {{{
+	AC_ARG_WITH(
+		[adic2-dir],
+		AS_HELP_STRING([--with-adic2-dir=DIR], [ADIC2 root directory]),
+		[ADIC2_ROOT=${withval}],
+		[ADIC2_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for ADIC2])
+	if test "x${ADIC2_ROOT}" == "xno"; then
+		HAVE_ADIC2=no
+	else
+		HAVE_ADIC2=yes
+		if ! test -d "${ADIC2_ROOT}"; then
+			AC_MSG_ERROR([ADIC2 directory provided (${ADIC2_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_ADIC2}])
+
+	dnl ADIC2 libraries and header files
+	if test "x${HAVE_ADIC2}" == "xyes"; then
+		ADIC2INCL="-DADIC2_DENSE -I${ADIC2_ROOT}/include -I${ADIC2_ROOT}/share/runtime_dense"
+		ADIC2LIB=""
+		AC_DEFINE([_HAVE_ADIC2_], [1], [with ADIC2 in ISSM src])
+		AC_SUBST([ADIC2INCL])
+		AC_SUBST([ADIC2LIB])
+	fi
+	AM_CONDITIONAL([ADIC2], [test "x${HAVE_ADIC2}" == "xyes"])
+	dnl }}}
+	dnl ATLAS {{{
+	AC_ARG_WITH(
+		[atlas-dir],
+		AS_HELP_STRING([--with-atlas-dir=DIR], [ATLAS root directory]),
+		[ATLAS_ROOT=${withval}],
+		[ATLAS_ROOT="no"]
+	)
+	AC_MSG_CHECKING(for ATLAS and CBLAS libraries)
+	if test "x${ATLAS_ROOT}" == "xno"; then
+		HAVE_ATLAS=no
+	else
+		HAVE_ATLAS=yes
+		if ! test -d "${ATLAS_ROOT}"; then
+			AC_MSG_ERROR([ATLAS directory provided (${ATLAS_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_ATLAS}])
+
+	dnl ATLAS libraries and header files
+	if test "x${HAVE_ATLAS}" == "xyes"; then
+		case "${host_os}" in
+			*cygwin*)
+				ATLASLIB="-L`cygpath -m ${ATLAS_ROOT}` -Wl,libatlas.lib  -Wl,libcblas.lib"
+			;;
+			*linux*)
+				ATLASLIB="-L${ATLAS_ROOT}/lib -lcblas -latlas -lm "
+			;;
+			*darwin*)
+				ATLASLIB="-L${ATLAS_ROOT}/lib -lcblas -latlas -lm "
+			;;
+		esac
+		AC_DEFINE([_HAVE_ATLAS_], [1], [with ATLAS in ISSM src])
+		AC_SUBST([ATLASLIB])
+	fi
+	dnl }}}
+	dnl GSL{{{
+	AC_ARG_WITH(
+		[gsl-dir],
+		AS_HELP_STRING([--with-gsl-dir=DIR], [GSL root directory]),
+		[GSL_ROOT=${withval}],
+		[GSL_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for GSL])
+	if test "x${GSL_ROOT}" == "xno"; then
+		HAVE_GSL=no
+	else
+		HAVE_GSL=yes
+		if ! test -d "${GSL_ROOT}"; then
+			AC_MSG_ERROR([GSL directory provided (${GSL_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_GSL}])
+
+	dnl GSL libraries and header files
+	if test "x${HAVE_GSL}" == "xyes"; then
+		GSLINCL="-I${GSL_ROOT}/include"
+		if test "x${HAVE_ATLAS}" == "xyes"; then
+			GSLLIB="-dy -L${GSL_ROOT}/lib -lgsl -L${ATLAS_ROOT}/lib -lcblas -latlas -lm"
+		else
+			GSLLIB="-L${GSL_ROOT}/lib -lgsl -lgslcblas -lm"
+		fi
+		AC_DEFINE([_HAVE_GSL_], [1], [with GSL in ISSM src])
+		AC_SUBST([GSLINCL])
+		AC_SUBST([GSLLIB])
+	fi
+	AM_CONDITIONAL([GSL], [test "x${HAVE_GSL}" == "xyes"])
+	dnl }}}
+	dnl AMPI (ADOL-C){{{
+	AC_ARG_WITH(
+		[ampi-dir],
+		AS_HELP_STRING([--with-ampi-dir=DIR], [Adjoinable MPI root directory]),
+		[AMPI_ROOT=${withval}],
+		[AMPI_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for AMPI])
+	if test "x${AMPI_ROOT}" == "xno"; then
+		HAVE_AMPI=no
+	else
+		HAVE_AMPI=yes
+		if ! test -d "${AMPI_ROOT}"; then
+			AC_MSG_ERROR([AMPI directory provided (${AMPI_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_AMPI}])
+
+	dnl AMPI libraries and header files
+	if test "x${HAVE_AMPI}" == "xyes"; then
+		AMPIINCL="-I${AMPI_ROOT}/include"
+		if test "x${ADOLC_ROOT}" == "xno"; then
+			AC_MSG_ERROR([cannot run AMPI without ADOL-C]);
+		fi
+		dnl AMPILIB="-dy -L${AMPI_ROOT}/lib -lampiCommon -L${ADOLC_ROOT}/lib -ladolc -L${AMPI_ROOT}/lib -lampiCommon -lampiBookkeeping -lampiTape"
+		dnl AMPILIB="-dy -L${AMPI_ROOT}/lib  -L${ADOLC_ROOT}/lib -Wl,--start-group,-lampiCommon,-ladolc,-lampiCommon,-lampiBookkeeping,-lampiTape,-lampiPlainC,-lampiADtoolStubsST,--end-group"
+		dnl AMPILIB="-L${AMPI_ROOT}/lib  -L${ADOLC_ROOT}/lib -Wl,--start-group -lampiCommon -ladolc -lampiCommon -lampiBookkeeping -lampiTape -lampiPlainC -lampiADtoolStubsST -Wl,--end-group"
+		dnl AMPILIB="${AMPI_ROOT}/lib/libampiCommon.so ${ADOLC_ROOT}/lib/libadolc.so  ${AMPI_ROOT}/lib/libampiCommon.so ${AMPI_ROOT}/lib/libampiBookkeeping.so ${AMPI_ROOT}/lib/libampiTape.so ${AMPI_ROOT}/lib/libampiPlainC.so  ${AMPI_ROOT}/lib/libampiADtoolStubsST.so"
+		dnl AMPILIB="-dy -L${AMPI_ROOT}/lib  -L${ADOLC_ROOT}/lib -lampiCommon -ladolc -lampiCommon -lampiBookkeeping -lampiTape -lampiPlainC -lampiADtoolStubsST"
+		AMPILIB="-dy -L${AMPI_ROOT}/lib  -lampiCommon -lampiBookkeeping -lampiTape"
+		AC_DEFINE([_HAVE_AMPI_], [1], [with AMPI in ISSM src])
+		AC_SUBST([AMPIINCL])
+		AC_SUBST([AMPILIB])
+	fi
+	AM_CONDITIONAL([AMPI], [test "x${HAVE_AMPI}" == "xyes"])
+	dnl }}}
+	dnl Adjoint MPI (CoDiPack){{{
+	AC_ARG_WITH(
+		[adjointmpi-dir],
+		AS_HELP_STRING([--with-adjointmpi-dir=DIR], [Adjoint MPI root directory]),
+		[ADJOINTMPI_ROOT=${withval}],
+		[ADJOINTMPI_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for Adjoint MPI])
+	if test "x${ADJOINTMPI_ROOT}" == "xno"; then
+		HAVE_ADJOINTMPI=no
+	else
+		HAVE_ADJOINTMPI=yes
+		if ! test -d "${ADJOINTMPI_ROOT}"; then
+			AC_MSG_ERROR([Adjoint MPI directory provided (${ADJOINTMPI_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_ADJOINTMPI}])
+
+	dnl Adjoint MPI libraries and header files
+	if test "x${HAVE_ADJOINTMPI}" == "xyes"; then
+		if test "x${CODIPACK_ROOT}" == "xno"; then
+			AC_MSG_ERROR([cannot run Adjoint MPI without CoDiPack]);
+		fi
+		ADJOINTMPIINCL="-I${ADJOINTMPI_ROOT}/include"
+		ADJOINTMPILIB="-L${ADJOINTMPI_ROOT}/lib  -lAMPI"
+		dnl Also set _HAVE_AMPI_, because the interface is (almost) the same as
+		dnl for AMPI
+		AC_DEFINE([_HAVE_AMPI_], [1], [with AMPI in ISSM src])
+		AC_DEFINE([_HAVE_ADJOINTMPI_], [1], [with Adjoint MPI in ISSM src])
+		AC_SUBST([ADJOINTMPIINCL])
+		AC_SUBST([ADJOINTMPILIB])
+	fi
+	AM_CONDITIONAL([ADJOINTMPI], [test "x${HAVE_ADJOINTMPI}" == "xyes"])
+	dnl }}}
+	dnl MeDiPack (CoDiPack, ADOL-C dev){{{
+	AC_ARG_WITH(
+		[medipack-dir],
+		AS_HELP_STRING([--with-medipack-dir=DIR], [MeDiPack root directory]),
+		[MEDIPACK_ROOT=${withval}],
+		[MEDIPACK_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for MeDiPack])
+	if test "x${MEDIPACK_ROOT}" == "xno"; then
+		HAVE_MEDIPACK=no
+	else
+		HAVE_MEDIPACK=yes
+		if ! test -d "${MEDIPACK_ROOT}"; then
+			AC_MSG_ERROR([MeDiPack directory provided (${MEDIPACK_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_MEDIPACK}])
+
+	dnl MeDiPack libraries and header files
+	if test "x${HAVE_MEDIPACK}" == "xyes"; then
+		if test "x${CODIPACK_ROOT}" == "xno"; then
+			AC_MSG_ERROR([cannot run MeDiPack without CoDiPack]);
+		fi
+		MEDIPACKINCL="-I${MEDIPACK_ROOT}/include -I${MEDIPACK_ROOT}/src"
+		dnl Also set _HAVE_AMPI_, because the interface is (almost) the same as
+		dnl for AMPI
+		AC_DEFINE([_HAVE_AMPI_], [1], [with AMPI in ISSM src])
+		AC_DEFINE([_HAVE_MEDIPACK_], [1], [with MeDiPack in ISSM src])
+		AC_SUBST([MEDIPACKINCL])
+	fi
+	AM_CONDITIONAL([MEDIPACK], [test "x${HAVE_MEDIPACK}" == "xyes"])
+	dnl }}}
+	dnl MPI{{{
+	AC_MSG_CHECKING(for MPI)
+
+	AC_ARG_WITH(
+		[mpi-include],
+		AS_HELP_STRING([--with-mpi-include=DIR], [MPI include directory, necessary for parallel build]),
+		[MPI_INCLUDE=${withval}],
+		[MPI_INCLUDE=""]
+	)
+
+	AC_ARG_WITH(
+		[mpi-libdir],
+		AS_HELP_STRING([--with-mpi-libdir=DIR], [MPI library directory, necessary for parallel build]),
+		[MPI_LIBDIR=${withval}],
+		[MPI_LIBDIR=""]
+	)
+
+	AC_ARG_WITH(
+		[mpi-libflags],
+		AS_HELP_STRING([--with-mpi-libflags=LIBS], [MPI libraries to be used, necessary for parallel build]),
+		[MPI_LIBFLAGS=${withval}],
+		[MPI_LIBFLAGS=""]
+	)
+
+	if test -z "${MPI_INCLUDE}"; then
+		HAVE_MPI=no
+	else
+		HAVE_MPI=yes
+
+		dnl Processing for Windows
+		dnl
+		dnl NOTE: We know $VENDOR cannot be empty at this point, so no need to
+		dnl		  check again in the following conditionals
+		dnl
+		if test "${VENDOR}" == "intel-win7-32"; then
+			MPI_LIBDIR=`cygpath -m ${MPI_LIBDIR}`
+			MPI_INCLUDE=`cygpath -m ${MPI_INCLUDE}`
+		elif test "${VENDOR}" == "intel-win7-64"; then
+			MPI_LIBDIR="/I`cygpath -m ${MPI_LIBDIR}`"
+			MPI_INCLUDE=`cygpath -m ${MPI_INCLUDE}`
+		elif test "${VENDOR}" == "MSVC-Win64" || test "${VENDOR}" == "MSVC-Win64-par"; then
+			MPI_LIBDIR=`cygpath -m ${MPI_LIBDIR}`
+			MPI_INCLUDE=`cygpath -m ${MPI_INCLUDE}`
+		fi
+
+		if test -z "${MPI_LIBDIR}"; then
+			MPILIB="${MPI_LIBFLAGS}"
+		else
+			MPILIB="-L${MPI_LIBDIR} ${MPI_LIBFLAGS}"
+		fi
+
+		if test "x${IS_WINDOWS}" == "xyes"; then
+			MPIINCL=/I"${MPI_INCLUDE}"
+		else
+			MPIINCL="-I${MPI_INCLUDE}"
+		fi
+
+		AC_DEFINE([_HAVE_MPI_], [1], [with MPI in ISSM src])
+		AC_DEFINE([HAVE_MPI], [1], [MPI flag for Dakota (DO NOT REMOVE)])
+		AC_SUBST([MPIINCL])
+		AC_SUBST([MPILIB])
+	fi
+	AM_CONDITIONAL([MPI], [test "x${HAVE_MPI}" == "xyes"])
+	AC_MSG_RESULT([${HAVE_MPI}])
+	dnl }}}
+	dnl PETSc{{{
+	AC_ARG_WITH(
+		[petsc-dir],
+		AS_HELP_STRING([--with-petsc-dir=DIR], [PETSc root directory, necessary for parallel build]),
+		[PETSC_ROOT=${withval}],
+		[PETSC_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for PETSc])
+	if test "x${PETSC_ROOT}" == "xno"; then
+		HAVE_PETSC=no
+	else
+		HAVE_PETSC=yes
+		if ! test -d "${PETSC_ROOT}"; then
+			AC_MSG_ERROR([PETSc directory provided (${PETSC_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_PETSC}])
+	AM_CONDITIONAL([PETSC], [test "x${HAVE_PETSC}" == "xyes"])
+
+	dnl PETSc libraries and header files
+	if test "x${HAVE_PETSC}" == "xyes"; then
+		AC_MSG_CHECKING(for PETSc version)
+		if ! test -f "${PETSC_ROOT}/include/petscversion.h"; then
+			AC_MSG_ERROR([PETSc not instaled correctly: file (${PETSC_ROOT}/include/petscversion.h) does not exist!]);
+		fi
+		PETSC_MAJOR=`cat ${PETSC_ROOT}/include/petscversion.h | grep "#define PETSC_VERSION_MAJOR" | sed 's/#define PETSC_VERSION_MAJOR//' | sed 's/ //g'`
+		PETSC_MINOR=`cat ${PETSC_ROOT}/include/petscversion.h | grep "#define PETSC_VERSION_MINOR" | sed 's/#define PETSC_VERSION_MINOR//' | sed 's/ //g'`
+		AC_DEFINE_UNQUOTED(_PETSC_MAJOR_, $PETSC_MAJOR, [PETSc version major])
+		AC_DEFINE_UNQUOTED(_PETSC_MINOR_, $PETSC_MINOR, [PETSc version minor])
+		AC_MSG_RESULT([${PETSC_MAJOR}.${PETSC_MINOR}])
+
+		dnl PETSC_VERSION_DATE_HG=`cat ${PETSC_ROOT}/include/petscversion.h | grep "#define PETSC_VERSION_DATE_HG" | sed 's/#define PETSC_VERSION_DATE_HG//' | sed 's/ //g' | sed -e 's/\"//g' `
+		PETSC_RELEASE=`cat ${PETSC_ROOT}/include/petscversion.h | grep "#define PETSC_VERSION_RELEASE" | sed 's/#define PETSC_VERSION_RELEASE//' | sed 's/ //g'`
+
+		AC_MSG_CHECKING(whether PETSc is the development version)
+		dnl if test "x${PETSC_VERSION_DATE_HG}" == "xunknown"; then
+		if test "${PETSC_RELEASE}" == "0"; then
+			AC_DEFINE([_HAVE_PETSCDEV_], [1], [with PETSc-dev])
+			AC_MSG_RESULT([yes])
+		else
+			AC_MSG_RESULT([no])
+		fi
+
+		AC_ARG_WITH(
+			[petsc-arch],
+			AS_HELP_STRING([--with-petsc-arch=DIR], [PETSc arch, necessary for PETSc < 3.0]),
+			[PETSC_ARCH=${withval}],
+			[PETSC_ARCH=""]
+		)
+
+		AC_MSG_CHECKING(for PETSc libraries and header files in ${PETSC_ROOT})
+		dnl To get PETSc's libraries,
+		dnl
+		dnl		cd $ISSM_DIR/externalpackages/petsc/src
+		dnl		make getlinklibs
+		dnl
+		PETSCINCL=" -I${PETSC_ROOT}/include"
+		dnl Add other location (not needed anymore since at least PETSc 3.0)
+		if test -n "${PETSC_ARCH}" && test -d "${PETSC_ROOT}/${PETSC_ARCH}/include"; then
+			PETSCINCL+=" ${PETSC_ROOT}/${PETSC_ARCH}/include"
+		fi
+		if test -n "${PETSC_ARCH}" && test -d "${PETSC_ROOT}/include/${PETSC_ARCH}"; then
+			PETSCINCL+=" ${PETSC_ROOT}/include/${PETSC_ARCH}"
+		fi
+
+		case "${host_os}" in
+			*cygwin*)
+				if test ${PETSC_MAJOR} -lt 3; then
+					PETSCLIB=-Wl,/LIBPATH:`cygpath -w ${PETSC_ROOT}/lib` -Wl,libpetscksp.lib  -Wl,libpetscdm.lib -Wl,libpetscmat.lib -Wl,libpetscvec.lib -Wl,libpetscsnes.lib  -Wl,libpetscts.lib -Wl,libmpiuni.lib -Wl,libpetsc.lib
+				else
+					PETSCLIB="/link -Wl,/LIBPATH:`cygpath -m ${PETSC_ROOT}/lib` -Wl,libpetsc.lib"
+					PETSCINCL="/I`cygpath -m ${PETSC_ROOT}/include`"
+				fi
+			;;
+			*linux*)
+				if test ${PETSC_MAJOR} -lt 3; then
+					PETSCLIB="-L${PETSC_ROOT}/lib -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsnes -lpetscts -lmpiuni -lpetsc"
+				else
+					PETSCLIB="-L${PETSC_ROOT}/lib -lpetsc -ldl"
+					if test ${PETSC_MAJOR} -gt 3 || test ${PETSC_MINOR} -ge 3; then
+						PETSCLIB+=" -lparmetis -lmetis"
+					fi
+				fi
+				if test "x$host_os_version" = "x3.0.101-0.31.1_1.0502.8394-cray_gem_s"; then
+					PETSCLIB="-L${PETSC_ROOT}/lib -lcraypetsc_gnu_real -lmetis"
+				fi
+			;;
+			*darwin*)
+				if test ${PETSC_MAJOR} -lt 3; then
+					PETSCLIB="-L${PETSC_ROOT}/lib -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsnes -lpetscts -lpetsc"
+				else
+					PETSCLIB="-L${PETSC_ROOT}/lib -lpetsc"
+					if test ${PETSC_MAJOR} -gt 3 || test ${PETSC_MINOR} -ge 3; then
+						PETSCLIB+=" -lmetis"
+					fi
+				fi
+			;;
+		esac
+		AC_MSG_RESULT([done])
+		AC_DEFINE([_HAVE_PETSC_], [1], [with PETSc in ISSM src])
+		AC_SUBST([PETSCINCL])
+		AC_SUBST([PETSCLIB])
+	fi
+	dnl }}}
+	dnl SCOTCH{{{
+	AC_ARG_WITH(
+		[scotch-dir],
+		AS_HELP_STRING([--with-scotch-dir=DIR], [SCOTCH root directory]),
+		[SCOTCH_ROOT=$withval],
+		[SCOTCH_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for SCOTCH])
+	if test "x${SCOTCH_ROOT}" == "xno"; then
 		HAVE_SCOTCH=no
 	else
 		HAVE_SCOTCH=yes
-		if ! test -d "$SCOTCH_ROOT"; then
-			AC_MSG_ERROR([scotch directory provided ($SCOTCH_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_SCOTCH)
-	AM_CONDITIONAL([SCOTCH],[test x$HAVE_SCOTCH = xyes])
-
-	dnl scotch libraries
-	if test "x$HAVE_SCOTCH" = "xyes"; then
-		SCOTCHINCL="-DNOFILEIO -I$SCOTCH_ROOT/include -DSCOTCH_VERSION=\\\"UNKNOWN\\\""
-		SCOTCHLIB="-L$SCOTCH_ROOT/lib -lnfioscotch -lnfioscotcherr -lnfioscotcherrexit "
-		AC_DEFINE([_HAVE_SCOTCH_],[1],[with Scotch in ISSM src])
+		if ! test -d "${SCOTCH_ROOT}"; then
+			AC_MSG_ERROR([SCOTCH directory provided (${SCOTCH_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SCOTCH}])
+	AM_CONDITIONAL([SCOTCH], [test "x${HAVE_SCOTCH}" == "xyes"])
+
+	dnl SCOTCH libraries and header files
+	if test "x${HAVE_SCOTCH}" == "xyes"; then
+		if test "x${SCOTCH_ROOT}" == "x${PETSC_ROOT}"; then
+			AC_DEFINE([_PETSC_SCOTCH_], [1], [is SCOTCH installed via PETSc])
+			SCOTCHINCL="-DNOFILEIO -I${SCOTCH_ROOT}/include -DSCOTCH_VERSION=\\\"UNKNOWN\\\""
+			SCOTCHLIB="-L${SCOTCH_ROOT}/lib -lnfioscotch -lnfioscotcherr -lnfioscotcherrexit "
+		else
+			SCOTCHINCL="-I${SCOTCH_ROOT}/include"
+			SCOTCHLIB="-L${SCOTCH_ROOT}/lib "
+			if test "x${HAVE_MPI}" == "xyes"; then
+				SCOTCHLIB+="-lptesmumps -lptscotch -lptscotcherr -lptscotcherrexit -lscotch"
+			else
+				SCOTCHLIB+="-lscotch -lscotcherr -lscotcherrexit"
+			fi
+		fi
+		AC_DEFINE([_HAVE_SCOTCH_], [1], [with SCOTCH in ISSM src])
 		AC_SUBST([SCOTCHINCL])
 		AC_SUBST([SCOTCHLIB])
 	fi
 	dnl }}}
-	dnl esmf{{{
-	AC_ARG_WITH([esmf-dir],
-		AS_HELP_STRING([--with-esmf-dir=DIR], [esmf root directory.]),
-		[ESMF_ROOT=$withval],[ESMF_ROOT="no"])
-
-	dnl Check whether esmf is enabled
-	AC_MSG_CHECKING([for esmf])
-	if test "x$ESMF_ROOT" = "xno" ; then
-		HAVE_ESMF=no
-	else
-		HAVE_ESMF=yes
-		if ! test -d "$ESMF_ROOT"; then
-			AC_MSG_ERROR([esmf directory provided ($ESMF_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_ESMF)
-
-	dnl esmf headers and libraries
-	if test "x$HAVE_ESMF" == "xyes"; then
-		ESMFINCL="-I$ESMF_ROOT/include"
-		ESMFLIB="-L$ESMF_ROOT/lib -lesmf"
-		AC_DEFINE([_HAVE_ESMF_],[1],[with esmf in ISSM src])
-		AC_SUBST([ESMFINCL])
-		AC_SUBST([ESMFLIB])
-	fi
-	AM_CONDITIONAL([ESMF], [test x$HAVE_ESMF = xyes])
-	dnl }}}
-	dnl codipack{{{
-	AC_ARG_WITH([codipack-dir],
-		AS_HELP_STRING([--with-codipack-dir=DIR], [CoDiPack root directory.]),
-		[CODIPACK_ROOT=$withval],[CODIPACK_ROOT="no"])
-
-	dnl Check whether codipack is enabled
-	AC_MSG_CHECKING([for CoDiPack])
-	if test "x$CODIPACK_ROOT" = "xno" ; then
-		HAVE_CODIPACK=no
-	else
-		HAVE_CODIPACK=yes
-		if ! test -d "$CODIPACK_ROOT"; then
-			AC_MSG_ERROR([codipack directory provided ($CODIPACK_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_CODIPACK)
-
-	dnl codipack headers and libraries
-	if test "x$HAVE_CODIPACK" == "xyes"; then
-		CODIPACKINCL="-I$CODIPACK_ROOT/include"
-		AC_DEFINE([_HAVE_CODIPACK_],[1],[with codipack in ISSM src])
-		AC_DEFINE([_HAVE_AD_],[1],[with AD in ISSM src])
-		AC_SUBST([CODIPACKINCL])
-	fi
-	AM_CONDITIONAL([CODIPACK], [test x$HAVE_CODIPACK = xyes])
-   AM_COND_IF(CODIPACK,[CXXFLAGS+=" -std=c++11"])
-	dnl }}}
-	dnl tapeallocation {{{
-	AC_ARG_ENABLE([tape-alloc], dnl feature
-		AS_HELP_STRING([--enable-tape-alloc],[turn tape allocation support on]),
-		[enable_tape_alloc=$enableval], [enable_tape_alloc=no])
-
-	dnl check whether enabled
-	AC_MSG_CHECKING(for tape memory allocation)
-	if test "x$enable_tape_alloc" = xyes; then
-		AC_DEFINE([_AD_TAPE_ALLOC_],[1],[Macro to enable a priori tape allocation for AD])
-	fi
-	AC_MSG_RESULT($enable_tape_alloc)
-	dnl }}}
-	dnl adolc{{{
-	AC_ARG_WITH([adolc-dir],
-		AS_HELP_STRING([--with-adolc-dir=DIR], [adolc root directory.]),
-		[ADOLC_ROOT=$withval],[ADOLC_ROOT="no"])
-
-	dnl Check whether adolc is enabled
-	AC_MSG_CHECKING([for adolc])
-	if test "x$ADOLC_ROOT" = "xno" ; then
-		HAVE_ADOLC=no
-	else
-		HAVE_ADOLC=yes
-		if ! test -d "$ADOLC_ROOT"; then
-			AC_MSG_ERROR([adolc directory provided ($ADOLC_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_ADOLC)
-
-	dnl adolc headers and libraries
-	if test "x$HAVE_ADOLC" == "xyes"; then
-		ADOLCINCL="-I$ADOLC_ROOT/include"
-		dnl ADOLCLIB="-L$ADOLC_ROOT/lib64 -ladolc" used to be the path
-		ADOLCLIB="-L$ADOLC_ROOT/lib -ladolc"
-		AC_DEFINE([_HAVE_ADOLC_],[1],[with adolc in ISSM src])
-		AC_DEFINE([_HAVE_AD_],[1],[with AD in ISSM src])
-		AC_SUBST([ADOLCINCL])
-		AC_SUBST([ADOLCLIB])
-	fi
-	AM_CONDITIONAL([ADOLC], [test x$HAVE_ADOLC = xyes])
-   AM_COND_IF(ADOLC,[CXXFLAGS+=" -std=c++11"])
-	dnl }}}
-	dnl adolc-version{{{
-	AC_ARG_WITH([adolc-version],
-		AS_HELP_STRING([--with-adolc-version=number], [adolc version.]),
-		[ADOLC_VERSION=$withval],[ADOLC_VERSION=2])
-	AC_MSG_CHECKING(for adolc-version)
-
-	AC_DEFINE_UNQUOTED([_ADOLC_VERSION_],$ADOLC_VERSION,[ADOLC version])
-	AC_MSG_RESULT($ADOLC_VERSION)
-	dnl }}}
-	dnl adic2{{{
-	AC_ARG_WITH([adic2-dir],
-	  AS_HELP_STRING([--with-adic2-dir=DIR], [adic2 root directory.]),
-	  [ADIC2_ROOT=$withval],[ADIC2_ROOT="no"])
-
-	dnl Check whether adic2 is enabled
-	AC_MSG_CHECKING([for adic2])
-	if test "x$ADIC2_ROOT" = "xno" ; then
-		HAVE_ADIC2=no
-	else
-		HAVE_ADIC2=yes
-		if ! test -d "$ADIC2_ROOT"; then
-			AC_MSG_ERROR([adic2 directory provided ($ADIC2_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_ADIC2)
-
-	dnl adic2 headers and libraries
-	if test "x$HAVE_ADIC2" == "xyes"; then
-		ADIC2INCL="-DADIC2_DENSE -I$ADIC2_ROOT/include -I$ADIC2_ROOT/share/runtime_dense/"
-		ADIC2LIB=""
-		AC_DEFINE([_HAVE_ADIC2_],[1],[with adic2 in ISSM src])
-		AC_SUBST([ADIC2INCL])
-		AC_SUBST([ADIC2LIB])
-	fi
-	AM_CONDITIONAL([ADIC2], [test x$HAVE_ADIC2 = xyes])
-	dnl }}}
-	dnl atlas{{{
-	AC_ARG_WITH([atlas-dir],
-	  AS_HELP_STRING([--with-atlas-dir=DIR],[atlas root directory]),
-	  [ATLAS_ROOT=$withval],[ATLAS_ROOT="no"])
-
-	dnl Check whether atlas is enabled
-	AC_MSG_CHECKING(for atlas and cblas libraries)
-	if test "x$ATLAS_ROOT" = "xno" ; then
-		HAVE_ATLAS=no
-	else
-		HAVE_ATLAS=yes
-		if ! test -d "$ATLAS_ROOT"; then
-			AC_MSG_ERROR([atlas directory provided ($ATLAS_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_ATLAS)
-
-	dnl atlas headers and libraries
-	if test "x$HAVE_ATLAS" == "xyes"; then
-		dnl: branch on whether we are running on windows or linux.
-		case "${host_os}" in
-			*cygwin*)
-			ATLASLIB="-L`cygpath -m $ATLAS_ROOT` -Wl,libatlas.lib  -Wl,libcblas.lib"
-			;;
-			*linux*)
-			ATLASLIB=-L"$ATLAS_ROOT/lib -lcblas -latlas -lm "
-			;;
-			*darwin*)
-			ATLASLIB=-L"$ATLAS_ROOT/lib -lcblas -latlas -lm"
-			;;
-		esac
-		AC_DEFINE([_HAVE_ATLAS_],[1],[with ATLAS in ISSM src])
-		AC_SUBST([ATLASLIB])
-	fi
-	dnl }}}
-	dnl gsl{{{
-	AC_ARG_WITH([gsl-dir],
-	  AS_HELP_STRING([--with-gsl-dir=DIR], [gsl root directory.]),
-	  [GSL_ROOT=$withval],[GSL_ROOT="no"])
-
-	dnl Check whether gsl is enabled
-	AC_MSG_CHECKING([for gsl])
-	if test "x$GSL_ROOT" = "xno" ; then
-		HAVE_GSL=no
-	else
-		HAVE_GSL=yes
-		if ! test -d "$GSL_ROOT"; then
-			AC_MSG_ERROR([gsl directory provided ($GSL_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_GSL)
-
-	dnl gsl headers and libraries
-	if test "x$HAVE_GSL" == "xyes"; then
-		GSLINCL="-I$GSL_ROOT/include"
-		if test "x$HAVE_ATLAS" = "xyes" ; then
-			GSLLIB="-dy -L$GSL_ROOT/lib -lgsl -L$ATLAS_ROOT/lib -lcblas -latlas -lm"
-		else
-			GSLLIB="-L$GSL_ROOT/lib -lgsl -lgslcblas -lm"
-		fi
-		AC_DEFINE([_HAVE_GSL_],[1],[with gsl in ISSM src])
-		AC_SUBST([GSLINCL])
-		AC_SUBST([GSLLIB])
-	fi
-	AM_CONDITIONAL([GSL], [test x$HAVE_GSL = xyes])
-	dnl }}}
-	dnl ampi (ADOLC){{{
-	AC_ARG_WITH([ampi-dir],
-	  AS_HELP_STRING([--with-ampi-dir=DIR], [adjoinable mpi root directory.]),
-	  [AMPI_ROOT=$withval],[AMPI_ROOT="no"])
-
-	dnl Check whether ampi is enabled
-	AC_MSG_CHECKING([for ampi])
-	if test "x$AMPI_ROOT" = "xno" ; then
-		HAVE_AMPI=no
-	else
-		HAVE_AMPI=yes
-		if ! test -d "$AMPI_ROOT"; then
-			AC_MSG_ERROR([ampi directory provided ($AMPI_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_AMPI)
-
-	dnl ampi headers and libraries
-	if test "x$HAVE_AMPI" == "xyes"; then
-		AMPIINCL="-I$AMPI_ROOT/include"
-		if test "x$ADOLC_ROOT" == "xno"; then
-			AC_MSG_ERROR([cannot run adjoinable mpi without adolc]);
-		fi
-		dnl AMPILIB="-dy -L$AMPI_ROOT/lib -lampiCommon -L$ADOLC_ROOT/lib -ladolc -L$AMPI_ROOT/lib -lampiCommon -lampiBookkeeping -lampiTape"
-		dnl AMPILIB="-dy -L$AMPI_ROOT/lib  -L$ADOLC_ROOT/lib -Wl,--start-group,-lampiCommon,-ladolc,-lampiCommon,-lampiBookkeeping,-lampiTape,-lampiPlainC,-lampiADtoolStubsST,--end-group"
-		dnl AMPILIB="-L$AMPI_ROOT/lib  -L$ADOLC_ROOT/lib -Wl,--start-group -lampiCommon -ladolc -lampiCommon -lampiBookkeeping -lampiTape -lampiPlainC -lampiADtoolStubsST -Wl,--end-group"
-		dnl AMPILIB="$AMPI_ROOT/lib/libampiCommon.so $ADOLC_ROOT/lib/libadolc.so  $AMPI_ROOT/lib/libampiCommon.so $AMPI_ROOT/lib/libampiBookkeeping.so $AMPI_ROOT/lib/libampiTape.so $AMPI_ROOT/lib/libampiPlainC.so  $AMPI_ROOT/lib/libampiADtoolStubsST.so"
-		dnl AMPILIB="-dy -L$AMPI_ROOT/lib  -L$ADOLC_ROOT/lib -lampiCommon -ladolc -lampiCommon -lampiBookkeeping -lampiTape -lampiPlainC -lampiADtoolStubsST"
-		AMPILIB="-dy -L$AMPI_ROOT/lib  -lampiCommon -lampiBookkeeping -lampiTape"
-		AC_DEFINE([_HAVE_AMPI_],[1],[with adjoinable mpi in ISSM src])
-		AC_SUBST([AMPIINCL])
-		AC_SUBST([AMPILIB])
-	fi
-	AM_CONDITIONAL([AMPI], [test x$HAVE_AMPI = xyes])
-	dnl }}}
-	dnl adjointmpi (CoDiPack){{{
-	AC_ARG_WITH([adjointmpi-dir],
-	  AS_HELP_STRING([--with-adjointmpi-dir=DIR], [adjoinable mpi root directory.]),
-	  [ADJOINTMPI_ROOT=$withval],[ADJOINTMPI_ROOT="no"])
-
-	dnl Check whether adjointmpi is enabled
-	AC_MSG_CHECKING([for adjointmpi])
-	if test "x$ADJOINTMPI_ROOT" = "xno" ; then
-		HAVE_ADJOINTMPI=no
-	else
-		HAVE_ADJOINTMPI=yes
-		if ! test -d "$ADJOINTMPI_ROOT"; then
-			AC_MSG_ERROR([adjointmpi directory provided ($ADJOINTMPI_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_ADJOINTMPI)
-
-	dnl adjointmpi headers and libraries
-	if test "x$HAVE_ADJOINTMPI" == "xyes"; then
-		if test "x$CODIPACK_ROOT" == "xno"; then
-			AC_MSG_ERROR([cannot run adjoint mpi without CoDiPack]);
-		fi
-		ADJOINTMPIINCL="-I$ADJOINTMPI_ROOT/include"
-		ADJOINTMPILIB="-L$ADJOINTMPI_ROOT/lib  -lAMPI"
-		dnl Also set _HAVE_AMPI_, because the interface is (almost) the
-		dnl same as for adjoinable mpi...
-		AC_DEFINE([_HAVE_AMPI_],[1],[with adjoint mpi in ISSM src])
-		AC_DEFINE([_HAVE_ADJOINTMPI_],[1],[with adjoint mpi in ISSM src])
-		AC_SUBST([ADJOINTMPIINCL])
-		AC_SUBST([ADJOINTMPILIB])
-	fi
-	AM_CONDITIONAL([ADJOINTMPI], [test x$HAVE_ADJOINTMPI = xyes])
-	dnl }}}
-	dnl medipack (CoDiPack, ADOLC dev){{{
-	AC_ARG_WITH([medipack-dir],
-	  AS_HELP_STRING([--with-medipack-dir=DIR], [MeDiPack root directory.]),
-	  [MEDIPACK_ROOT=$withval],[MEDIPACK_ROOT="no"])
-
-	dnl Check whether medipack is enabled
-	AC_MSG_CHECKING([for medipack])
-	if test "x$MEDIPACK_ROOT" = "xno" ; then
-		HAVE_MEDIPACK=no
-	else
-		HAVE_MEDIPACK=yes
-		if ! test -d "$MEDIPACK_ROOT"; then
-			AC_MSG_ERROR([medipack directory provided ($MEDIPACK_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_MEDIPACK)
-
-	dnl medipack headers and libraries
-	if test "x$HAVE_MEDIPACK" == "xyes"; then
-		if test "x$CODIPACK_ROOT" == "xno"; then
-			AC_MSG_ERROR([cannot run MeDiPack without CoDiPack]);
-		fi
-		MEDIPACKINCL="-I$MEDIPACK_ROOT/include -I$MEDIPACK_ROOT/src"
-		dnl Also set _HAVE_AMPI_, because the interface is (almost) the
-		dnl same as for adjoinable mpi...
-		AC_DEFINE([_HAVE_AMPI_],[1],[with adjoint mpi in ISSM src])
-		AC_DEFINE([_HAVE_MEDIPACK_],[1],[with MeDiPack in ISSM src])
-		AC_SUBST([MEDIPACKINCL])
-	fi
-	AM_CONDITIONAL([MEDIPACK], [test x$HAVE_MEDIPACK = xyes])
-
-	dnl }}}
-	dnl rose{{{
-	AC_ARG_WITH([rose-dir],
-	  AS_HELP_STRING([--with-rose-dir=DIR], [rose root directory.]),
-	  [ROSE_ROOT=$withval],[ROSE_ROOT="no"])
-
-	dnl Check whether rose is enabled
-	AC_MSG_CHECKING([for rose])
-	if test "x$ROSE_ROOT" = "xno" ; then
-		HAVE_ROSE=no
-	else
-		HAVE_ROSE=yes
-		if ! test -d "$ROSE_ROOT"; then
-			AC_MSG_ERROR([rose directory provided ($ROSE_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_ROSE)
-	AM_CONDITIONAL([ROSE],[test x$HAVE_ROSE = xyes])
-
-	dnl library and header files
-	if test "x$HAVE_ROSE" = "xyes"; then
-		ROSEINCL="-I$ROSE_ROOT/include"
-		ROSELIB=""
-		AC_DEFINE([_HAVE_ROSE_],[1],[with rose in ISSM src])
-		AC_SUBST([ROSEINCL])
-		AC_SUBST([ROSELIB])
-	fi
-	dnl }}}
-	dnl mpi{{{
-	AC_MSG_CHECKING(for mpi)
-
-	AC_ARG_WITH([mpi-include],
-	  AS_HELP_STRING([--with-mpi-include=DIR],[mpi include directory, necessary for parallel build]),
-	  [MPI_INCLUDE=$withval],[MPI_INCLUDE=""])
-
-	AC_ARG_WITH([mpi-libdir],
-	  AS_HELP_STRING([--with-mpi-libdir=DIR],[mpi lib directory, necessary for parallel build]),
-	  [MPI_LIBDIR=$withval],[MPI_LIBDIR=""])
-
-	AC_ARG_WITH([mpi-libflags],
-	  AS_HELP_STRING([--with-mpi-libflags=LIBS],[mpi libraries to be used, necessary for parallel build]),
-	  [MPI_LIBFLAGS=$withval],[MPI_LIBFLAGS=""])
-
-
-	if test -z "$MPI_INCLUDE" ; then
-		HAVE_MPI=no
-	else
-		HAVE_MPI=yes
-
-		dnl Processing for windows
-		if  test x$VENDOR = xintel-win7-32; then
-			MPI_LIBDIR=`cygpath -m $MPI_LIBDIR`
-			MPI_INCLUDE=`cygpath -m $MPI_INCLUDE`
-		elif test x$VENDOR = xintel-win7-64; then
-			MPI_LIBDIR="/I`cygpath -m $MPI_LIBDIR`"
-			MPI_INCLUDE=`cygpath -m $MPI_INCLUDE`
-		elif test x$VENDOR = xMSVC-Win64 || test x$VENDOR = xMSVC-Win64-par; then
-			MPI_LIBDIR=`cygpath -m $MPI_LIBDIR`
-			MPI_INCLUDE=`cygpath -m $MPI_INCLUDE`
-		fi
-
-		if test -z "$MPI_LIBDIR"; then
-			MPILIB="$MPI_LIBFLAGS"
-		else
-			MPILIB="-L$MPI_LIBDIR $MPI_LIBFLAGS"
-		fi
-
-		if  test x$IS_WINDOWS = xyes; then
-			MPIINCL=/I"$MPI_INCLUDE"
-		else
-			MPIINCL=-I"$MPI_INCLUDE"
-		fi
-
-		AC_DEFINE([_HAVE_MPI_],[1],[with Mpi in ISSM src])
-		AC_DEFINE([HAVE_MPI],[1],[Mpi Flag for Dakota (DO NOT REMOVE)])
-		AC_SUBST([MPIINCL])
-		AC_SUBST([MPILIB])
-	fi
-	AM_CONDITIONAL([MPI], [test x$HAVE_MPI = xyes])
-	AC_MSG_RESULT($HAVE_MPI)
-	dnl }}}
-	dnl petsc{{{
-	AC_ARG_WITH([petsc-dir],
-	  AS_HELP_STRING([--with-petsc-dir=DIR],[PETSc root directory, necessary for parallel build]),
-	  [PETSC_ROOT=$withval],[PETSC_ROOT="no"])
-
-	dnl Check whether petsc is enabled
-	AC_MSG_CHECKING([for petsc])
-	if test "x$PETSC_ROOT" = "xno" ; then
-		HAVE_PETSC=no
-	else
-		HAVE_PETSC=yes
-		if ! test -d "$PETSC_ROOT"; then
-			AC_MSG_ERROR([petsc directory provided ($PETSC_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_PETSC)
-	AM_CONDITIONAL([PETSC],[test x$HAVE_PETSC = xyes])
-
-	dnl library and header files
-	if test "x$HAVE_PETSC" = "xyes"; then
-		AC_MSG_CHECKING(for petsc version)
-	   if ! test -f "$PETSC_ROOT/include/petscversion.h"; then
-			AC_MSG_ERROR([PETSc not instaled corretly: file ($PETSC_ROOT/include/petscversion.h) does not exist]);
-		fi
-		PETSC_MAJOR=`cat $PETSC_ROOT/include/petscversion.h | grep "#define PETSC_VERSION_MAJOR" | sed 's/#define PETSC_VERSION_MAJOR//' | sed 's/ //g'`
-		PETSC_MINOR=`cat $PETSC_ROOT/include/petscversion.h | grep "#define PETSC_VERSION_MINOR" | sed 's/#define PETSC_VERSION_MINOR//' | sed 's/ //g'`
-		AC_DEFINE_UNQUOTED([_PETSC_MAJOR_],$PETSC_MAJOR,[PETSc version major])
-		AC_DEFINE_UNQUOTED([_PETSC_MINOR_],$PETSC_MINOR,[PETSc version minor])
-		AC_MSG_RESULT($PETSC_MAJOR.$PETSC_MINOR)
-
-		PETSC_VERSION_DATE_HG=`cat $PETSC_ROOT/include/petscversion.h | grep "#define PETSC_VERSION_DATE_HG" | sed 's/#define PETSC_VERSION_DATE_HG//' | sed 's/ //g' | sed -e 's/\"//g' `
-		PETSC_RELEASE=`cat $PETSC_ROOT/include/petscversion.h | grep "#define PETSC_VERSION_RELEASE" | sed 's/#define PETSC_VERSION_RELEASE//' | sed 's/ //g'`
-
-		AC_MSG_CHECKING(whether petsc is the development version)
-		dnl if test x$PETSC_VERSION_DATE_HG = xunknown; then
-		if test "$PETSC_RELEASE" = "0"; then
-		   AC_DEFINE([_HAVE_PETSCDEV_],[1],[with PETSc-dev])
-			AC_MSG_RESULT(yes)
-		else
-			AC_MSG_RESULT(no)
-		fi
-
-		AC_ARG_WITH([petsc-arch],
-		  AS_HELP_STRING([--with-petsc-arch=DIR],[PETSc arch, necessary for PETSc < 3.0]),
-		  [PETSC_ARCH=$withval],[PETSC_ARCH=""])
-
-		AC_MSG_CHECKING(for petsc headers and libraries in $PETSC_ROOT)
-		dnl To ge PETSc's libraries:
-		dnl cd externalpackages/petsc/src
-		dnl make getlinklibs
-		PETSCINCL=" -I$PETSC_ROOT/include"
-		dnl Add other location (not needed anymore since at least PETSc 3.0)
-		if test "x$PETSC_ARCH" != "x" && test -d "$PETSC_ROOT/$PETSC_ARCH/include"; then
-		 PETSCINCL+=" $PETSC_ROOT/$PETSC_ARCH/include"
-		fi
-		if test "x$PETSC_ARCH" != "x" && test -d "$PETSC_ROOT/include/$PETSC_ARCH"; then
-		 PETSCINCL+=" $PETSC_ROOT/include/$PETSC_ARCH"
-		fi
-
-		case "${host_os}" in
-				*cygwin*)
-				if test $PETSC_MAJOR -lt 3 ; then
-					PETSCLIB=-Wl,/LIBPATH:`cygpath -w $PETSC_ROOT/lib`  -Wl,libpetscksp.lib  -Wl,libpetscdm.lib  -Wl,libpetscmat.lib  -Wl,libpetscvec.lib  -Wl,libpetscsnes.lib  -Wl,libpetscts.lib  -Wl,libmpiuni.lib  -Wl,libpetsc.lib
-				else
-					PETSCLIB="/link -Wl,/LIBPATH:`cygpath -m $PETSC_ROOT/lib`  -Wl,libpetsc.lib"
-					PETSCINCL="/I`cygpath -m $PETSC_ROOT/include`"
-				fi
-				;;
-				*linux*)
-				if test $PETSC_MAJOR -lt 3 ; then
-					PETSCLIB="-L$PETSC_ROOT/lib -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsnes -lpetscts -lmpiuni -lpetsc"
-				else
-					PETSCLIB="-L$PETSC_ROOT/lib -lpetsc -ldl"
-					if test $PETSC_MAJOR -gt 3 || test $PETSC_MINOR -ge 3; then PETSCLIB+=" -lparmetis -lmetis"; fi
-				fi
-				if test "x$host_os_version" = "x3.0.101-0.31.1_1.0502.8394-cray_gem_s" ; then
-					PETSCLIB="-L$PETSC_ROOT/lib -lcraypetsc_gnu_real -lmetis"
-				fi
-				;;
-				*darwin*)
-				if test $PETSC_MAJOR -lt 3 ; then
-					PETSCLIB="-L$PETSC_ROOT/lib -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsnes -lpetscts -lpetsc"
-				else
-					PETSCLIB="-L$PETSC_ROOT/lib -lpetsc"
-					if test $PETSC_MAJOR -gt 3 || test $PETSC_MINOR -ge 3; then PETSCLIB+=" -lmetis"; fi
-				fi
-				;;
-		esac
-		AC_MSG_RESULT(done)
-		AC_DEFINE([_HAVE_PETSC_],[1],[with PETSc in ISSM src])
-		AC_SUBST([PETSCINCL])
-		AC_SUBST([PETSCLIB])
-	fi
-	dnl }}}
-	dnl metis{{{
-	if test "$HAVE_PETSC" = "yes" && test "x$PETSC_MAJOR" = "x3" && test $PETSC_MINOR -ge 3 && test "x$VENDOR" != "xMSVC-Win64" && test "x$VENDOR" != "xMSVC-Win64-par"; then
-		dnl in petsc >=3.3, metis is provided
+	dnl METIS{{{
+
+	dnl NOTE: We know $VENDOR cannot be empty at this point, so no need to
+	dnl		  check again in the following conditionals
+	dnl
+	if test "x${HAVE_PETSC}" == "xyes" && test "x${PETSC_MAJOR}" == "x3" && test ${PETSC_MINOR} -ge 3 && test "${VENDOR}" != "MSVC-Win64" && test "${VENDOR}" != "MSVC-Win64-par"; then
+		dnl In PETSc >=3.3, METIS is provided
 		HAVE_METIS="yes"
-		AC_DEFINE([_METIS_VERSION_],[5],[ Metis version number])
-		AC_DEFINE([_HAVE_METIS_],[1],[with Metis in ISSM src])
-	else
-		AC_ARG_WITH([metis-dir],
-		  AS_HELP_STRING([--with-metis-dir=DIR],[metis root directory. necessary for serial build]),
-		  [METIS_ROOT=$withval],[METIS_ROOT="no"])
-
-		dnl Check whether metis is enabled
-		AC_MSG_CHECKING([for metis])
-		if test "x$METIS_ROOT" = "xno" ; then
+		AC_DEFINE([_METIS_VERSION_], [5], [METIS version number])
+		AC_DEFINE([_HAVE_METIS_], [1], [with METIS in ISSM src])
+	else
+		AC_ARG_WITH(
+			[metis-dir],
+			AS_HELP_STRING([--with-metis-dir=DIR], [METIS root directory, necessary for serial build]),
+			[METIS_ROOT=${withval}],
+			[METIS_ROOT="no"]
+		)
+		AC_MSG_CHECKING([for METIS])
+		if test "x${METIS_ROOT}" == "xno"; then
 			HAVE_METIS=no
 		else
 			HAVE_METIS=yes
-			if ! test -d "$METIS_ROOT"; then
-				AC_MSG_ERROR([metis directory provided ($METIS_ROOT) does not exist]);
+			if ! test -d "${METIS_ROOT}"; then
+				AC_MSG_ERROR([METIS directory provided (${METIS_ROOT}) does not exist!]);
 			fi
 		fi
-		AC_MSG_RESULT($HAVE_METIS)
-		AM_CONDITIONAL([METIS],[test x$HAVE_METIS = xyes])
-
-		dnl library and header files
-		if test "x$HAVE_METIS" = "xyes"; then
-
-			AC_MSG_CHECKING(for metis headers and libraries in $METIS_ROOT)
-			dnl first figure out version of metis: does the VERSION file exist?
-			if test -e "$METIS_ROOT/VERSION"; then
+		AC_MSG_RESULT([${HAVE_METIS}])
+		AM_CONDITIONAL([METIS], [test "x${HAVE_METIS}" == "xyes"])
+
+		dnl METIS libraries and header files
+		if test "x${HAVE_METIS}" == "xyes"; then
+			AC_MSG_CHECKING(for METIS libraries and header files in ${METIS_ROOT})
+			dnl Retrieve METIS version (does the VERSION file exist?)
+			if test -f "${METIS_ROOT}/VERSION"; then
 				METIS_VERSION=4
 			else
@@ -1266,152 +1349,155 @@
 			fi
 
-			if test "$METIS_VERSION" = "4" ; then
-				METISINCL=-I"$METIS_ROOT/Lib"
+			if test "x${METIS_VERSION}" == "x4"; then
+				METISINCL="-I${METIS_ROOT}/Lib"
 				case "${host_os}" in
 					*cygwin*)
-					METISINCL="/I`cygpath -m $METIS_ROOT/Lib`"
-					METISLIB="-Wl,/link -Wl,/LIBPATH:`cygpath -m $METIS_ROOT` -Wl,libmetis.lib"
+						METISINCL="/I`cygpath -m ${METIS_ROOT}/Lib`"
+						METISLIB="-Wl,/link -Wl,/LIBPATH:`cygpath -m ${METIS_ROOT}` -Wl,libmetis.lib"
 					;;
 					*linux*)
-					METISLIB=-L"$METIS_ROOT/ -lmetis"
+						METISLIB="-L${METIS_ROOT} -lmetis"
 					;;
 					*darwin*)
-					METISLIB=-L"$METIS_ROOT/ -lmetis"
+						METISLIB="-L${METIS_ROOT} -lmetis"
 					;;
 				esac
-				AC_DEFINE([_METIS_VERSION_],[4],[ Metis version number])
+				AC_DEFINE([_METIS_VERSION_], [4], [ METIS version number])
 			fi
 
-			if test "$METIS_VERSION" = "5" ; then
+			if test "x${METIS_VERSION}" == "x5"; then
 				case "${host_os}" in
 					*cygwin*)
-					METISLIB="-L$METIS_ROOT libmetis.lib"
+						METISLIB="-L${METIS_ROOT} libmetis.lib"
 					;;
 					*linux*)
-					METISLIB=-L"$METIS_ROOT/lib -lmetis"
+						METISLIB="-L${METIS_ROOT}/lib -lmetis"
 					;;
 					*darwin*)
-					METISLIB=-L"$METIS_ROOT/lib -lmetis"
+						METISLIB="-L${METIS_ROOT}/lib -lmetis"
 					;;
 				esac
-				METISINCL=-I"$METIS_ROOT/include"
-				AC_DEFINE([_METIS_VERSION_],[5],[ Metis version number])
+				METISINCL="-I${METIS_ROOT}/include"
+				AC_DEFINE([_METIS_VERSION_], [5], [METIS version number])
 			fi
 
-			AC_DEFINE([_HAVE_METIS_],[1],[with Metis in ISSM src])
+			AC_DEFINE([_HAVE_METIS_], [1], [with METIS in ISSM src])
 			AC_SUBST([METISINCL])
 			AC_SUBST([METISLIB])
 		fi
 	fi
-	AM_CONDITIONAL([METIS],[test x$HAVE_METIS = xyes])
-	dnl }}}
-	dnl tao{{{
-	AC_ARG_WITH([tao-dir],
-		AS_HELP_STRING([--with-tao-dir=DIR], [tao root directory.]),
-		[TAO_ROOT=$withval],[TAO_ROOT="no"])
-
-	dnl Check whether tao is enabled
-	AC_MSG_CHECKING([for tao])
-
-	if test "$HAVE_PETSC" = "yes" && test "x$PETSC_MAJOR" = "x3" && test $PETSC_MINOR -ge 5; then
-		dnl in petsc >=3.5, tao is provided
+	AM_CONDITIONAL([METIS], [test "x${HAVE_METIS}" == "xyes"])
+	dnl }}}
+	dnl Toolkit for Advanced Optimization (TAO){{{
+	AC_ARG_WITH(
+		[tao-dir],
+		AS_HELP_STRING([--with-tao-dir=DIR], [TAO root directory]),
+		[TAO_ROOT=${withval}],
+		[TAO_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for TAO])
+
+	if test "x${HAVE_PETSC}" == "xyes" && test "x${PETSC_MAJOR}" == "x3" && test ${PETSC_MINOR} -ge 5; then
+		dnl In PETSc >= 3.5, TAO is provided
 		HAVE_TAO="yes"
-		AC_DEFINE([_HAVE_TAO_],[1],[with Tao in ISSM src])
-		AC_MSG_RESULT($HAVE_TAO)
-	else
-
-		if test "x$TAO_ROOT" = "xno" ; then
+		AC_DEFINE([_HAVE_TAO_], [1], [with TAO in ISSM src])
+		AC_MSG_RESULT([${HAVE_TAO}])
+	else
+		if test "x${TAO_ROOT}" == "xno"; then
 			HAVE_TAO=no
 		else
 			HAVE_TAO=yes
-			if ! test -d "$TAO_ROOT"; then
-				AC_MSG_ERROR([tao directory provided ($TAO_ROOT) does not exist]);
+			if ! test -d "${TAO_ROOT}"; then
+				AC_MSG_ERROR([TAO directory provided (${TAO_ROOT}) does not exist!]);
 			fi
 		fi
-		AC_MSG_RESULT($HAVE_TAO)
-
-		dnl tao headers and libraries
-		if test "x$HAVE_TAO" == "xyes"; then
-		  TAOINCL="-I$TAO_ROOT/ -I$TAO_ROOT/include -I$TAO_ROOT/bmake/ "
-		  TAOLIB="-L$TAO_ROOT/lib -ltao -lpetsc"
-		  AC_DEFINE([_HAVE_TAO_],[1],[with Tao in ISSM src])
-		  AC_SUBST([TAOINCL])
-		  AC_SUBST([TAOLIB])
-		fi
-	fi
-	dnl }}}
-	dnl m1qn3{{{
-	AC_ARG_WITH([m1qn3-dir],
-		AS_HELP_STRING([--with-m1qn3-dir=DIR], [m1qn3 root directory.]),
-		[M1QN3_ROOT=$withval],[M1QN3_ROOT="no"])
-
-	dnl Check whether m1qn3 is enabled
-	AC_MSG_CHECKING([for m1qn3])
-	if test "x$M1QN3_ROOT" = "xno" ; then
+		AC_MSG_RESULT([${HAVE_TAO}])
+
+		dnl TAO libraries and header files
+		if test "x${HAVE_TAO}" == "xyes"; then
+			TAOINCL="-I${TAO_ROOT} -I${TAO_ROOT}/include -I${TAO_ROOT}/bmake"
+			TAOLIB="-L${TAO_ROOT}/lib -ltao -lpetsc"
+			AC_DEFINE([_HAVE_TAO_], [1], [with Tao in ISSM src])
+			AC_SUBST([TAOINCL])
+			AC_SUBST([TAOLIB])
+		fi
+	fi
+	dnl }}}
+	dnl M1QN3{{{
+	AC_ARG_WITH(
+		[m1qn3-dir],
+		AS_HELP_STRING([--with-m1qn3-dir=DIR], [M1QN3 root directory]),
+		[M1QN3_ROOT=${withval}],
+		[M1QN3_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for M1QN3])
+	if test "x${M1QN3_ROOT}" == "xno"; then
 		HAVE_M1QN3=no
 	else
 		HAVE_M1QN3=yes
-		if ! test -d "$M1QN3_ROOT"; then
-			AC_MSG_ERROR([m1qn3 directory provided ($M1QN3_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_M1QN3)
-
-	dnl m1qn3 headers and libraries
-	if test "x$HAVE_M1QN3" == "xyes"; then
-	  M1QN3LIB="$M1QN3_ROOT/libm1qn3.a $M1QN3_ROOT/libddot.a"
-	  AC_DEFINE([_HAVE_M1QN3_],[1],[with M1QN3 in ISSM src])
-	  AC_SUBST([M1QN3LIB])
-	fi
-	dnl }}}
-	dnl proj.4{{{
-	AC_ARG_WITH([proj4-dir],
-		AS_HELP_STRING([--with-proj4-dir=DIR], [proj4 root directory.]),
-		[PROJ4_ROOT=$withval],[PROJ4_ROOT="no"])
-
-	dnl Check whether proj4 is enabled
-	AC_MSG_CHECKING([for proj.4])
-	if test "x$PROJ4_ROOT" = "xno" ; then
+		if ! test -d "${M1QN3_ROOT}"; then
+			AC_MSG_ERROR([M1QN3 directory provided (${M1QN3_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_M1QN3}])
+
+	dnl M1QN3 libraries and header files
+	if test "x${HAVE_M1QN3}" == "xyes"; then
+		M1QN3LIB="${M1QN3_ROOT}/libm1qn3.a ${M1QN3_ROOT}/libddot.a"
+		AC_DEFINE([_HAVE_M1QN3_], [1], [with M1QN3 in ISSM src])
+		AC_SUBST([M1QN3LIB])
+	fi
+	dnl }}}
+	dnl PROJ.4{{{
+	AC_ARG_WITH(
+		[proj4-dir],
+		AS_HELP_STRING([--with-proj4-dir=DIR], [PROJ.4 root directory]),
+		[PROJ4_ROOT=${withval}],
+		[PROJ4_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for PROJ.4])
+	if test "x${PROJ4_ROOT}" == "xno"; then
 		HAVE_PROJ4=no
 	else
 		HAVE_PROJ4=yes
-		if ! test -d "$PROJ4_ROOT"; then
-			AC_MSG_ERROR([proj4 directory provided ($PROJ4_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_PROJ4)
-
-	dnl proj4 headers and libraries
-	if test "x$HAVE_PROJ4" == "xyes"; then
-	  PROJ4INCL="-I$PROJ4_ROOT/include "
-	  PROJ4LIB="-L$PROJ4_ROOT/lib -lproj"
-	  AC_DEFINE([_HAVE_PROJ4_],[1],[with PROJ4 in ISSM src])
-	  AC_SUBST([PROJ4INCL])
-	  AC_SUBST([PROJ4LIB])
-	fi
-	AM_CONDITIONAL([PROJ4],[test x$HAVE_PROJ4 = xyes])
-	dnl }}}
-	dnl slepc{{{
-	AC_ARG_WITH([slepc-dir],
-	  AS_HELP_STRING([--with-slepc-dir=DIR],[slepc root directory]),
-	  [SLEPC_ROOT=$withval],[SLEPC_ROOT="no"])
-
-	dnl Check whether slepc is enabled
-	AC_MSG_CHECKING([for slepc])
-	if test "x$SLEPC_ROOT" = "xno" ; then
+		if ! test -d "${PROJ4_ROOT}"; then
+			AC_MSG_ERROR([PROJ.4 directory provided (${PROJ4_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_PROJ4}])
+
+	dnl PROJ.4 libraries and header files
+	if test "x${HAVE_PROJ4}" == "xyes"; then
+		PROJ4INCL="-I${PROJ4_ROOT}/include"
+		PROJ4LIB="-L${PROJ4_ROOT}/lib -lproj"
+		AC_DEFINE([_HAVE_PROJ4_], [1], [with PROJ4 in ISSM src])
+		AC_SUBST([PROJ4INCL])
+		AC_SUBST([PROJ4LIB])
+	fi
+	AM_CONDITIONAL([PROJ4], [test "x${HAVE_PROJ4}" == "xyes"])
+	dnl }}}
+	dnl SLEPc{{{
+	AC_ARG_WITH(
+		[slepc-dir],
+		AS_HELP_STRING([--with-slepc-dir=DIR], [SLEPc root directory]),
+		[SLEPC_ROOT=${withval}],
+		[SLEPC_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for SLEPc])
+	if test "x${SLEPC_ROOT}" == "xno"; then
 		HAVE_SLEPC=no
 	else
 		HAVE_SLEPC=yes
-		if ! test -d "$SLEPC_ROOT"; then
-			AC_MSG_ERROR([slepc directory provided ($SLEPC_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_SLEPC)
-
-	dnl slepc headers and libraries
-	if test "x$HAVE_SLEPC" == "xyes"; then
-		SLEPCINCL=-I"$SLEPC_ROOT/include"
-		SLEPCLIB=-L"$SLEPC_ROOT/lib/ -lslepc"
-		AC_DEFINE([_HAVE_SLEPC_],[1],[with Slepc in ISSM src])
+		if ! test -d "${SLEPC_ROOT}"; then
+			AC_MSG_ERROR([SLEPc directory provided (${SLEPC_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SLEPC}])
+
+	dnl SLEPc libraries and header files
+	if test "x${HAVE_SLEPC}" == "xyes"; then
+		SLEPCINCL="-I${SLEPC_ROOT}/include"
+		SLEPCLIB="-L${SLEPC_ROOT}/lib -lslepc"
+		AC_DEFINE([_HAVE_SLEPC_], [1], [with SLEPc in ISSM src])
 		AC_SUBST([SLEPCINCL])
 		AC_SUBST([SLEPCLIB])
@@ -1419,150 +1505,164 @@
 	dnl }}}
 	dnl shapelib{{{
-	AC_ARG_WITH([shapelib-dir],
-	  AS_HELP_STRING([--with-shapelib-dir=DIR], [shapelib root directory]),
-	  [SHAPELIB_ROOT=$withval],[SHAPELIB_ROOT="no"])
-
-	dnl Check whether shapelib is enabled
+	AC_ARG_WITH(
+		[shapelib-dir],
+		AS_HELP_STRING([--with-shapelib-dir=DIR], [shapelib root directory]),
+		[SHAPELIB_ROOT=${withval}],
+		[SHAPELIB_ROOT="no"]
+	)
 	AC_MSG_CHECKING([for shapelib])
-	if test "x$SHAPELIB_ROOT" = "xno" ; then
+	if test "x${SHAPELIB_ROOT}" == "xno"; then
 		HAVE_SHAPELIB=no
 	else
 		HAVE_SHAPELIB=yes
-		if ! test -d "$SHAPELIB_ROOT"; then
-			AC_MSG_ERROR([shapelib directory provided ($SHAPELIB_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_SHAPELIB)
-
-	dnl shapelib headers and libraries
-	if test "x$HAVE_SHAPELIB" == "xyes"; then
-		SHAPELIBINCL=-I"$SHAPELIB_ROOT/include"
-		SHAPELIBLIB=-L"$SHAPELIB_ROOT/lib/ -lshape"
-		AC_DEFINE([_HAVE_SHAPELIB_],[1],[with Shapelib in ISSM src])
+		if ! test -d "${SHAPELIB_ROOT}"; then
+			AC_MSG_ERROR([shapelib directory provided (${SHAPELIB_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SHAPELIB}])
+
+	dnl shapelib libraries and header files
+	if test "x${HAVE_SHAPELIB}" == "xyes"; then
+		SHAPELIBINCL="-I${SHAPELIB_ROOT}/include"
+		SHAPELIBLIB="-L${SHAPELIB_ROOT}/lib -lshape"
+		AC_DEFINE([_HAVE_SHAPELIB_], [1], [with shapelib in ISSM src])
 		AC_SUBST([SHAPELIBINCL])
 		AC_SUBST([SHAPELIBLIB])
 	fi
 	dnl }}}
-	dnl scalapack{{{
-
-	dnl Here, either just the directory is provided, or the library, we handle both cases
-	AC_ARG_WITH([scalapack-dir],
-	  AS_HELP_STRING([--with-scalapack-dir=DIR],[scalapack root directory]),
-	  [SCALAPACK_ROOT=$withval],[SCALAPACK_ROOT="no"])
-
-	AC_ARG_WITH([scalapack-lib],
-	  AS_HELP_STRING([--with-scalapack-lib=LIBS],[scalapack libraries to include]),
-	  [SCALAPACKLIB=$withval],[SCALAPACKLIB="no"])
-
-	dnl Check whether scalapack is enabled
-	AC_MSG_CHECKING([for scalapack])
-	if test "x$SCALAPACK_ROOT" = "xno" && test "x$SCALAPACKLIB" = "xno"; then
-			HAVE_SCALAPACK=no
-			SCALAPACKLIB=
-	else if test "x$SCALAPACK_ROOT" != "xno"; then
-		if ! test -d "$SCALAPACK_ROOT"; then
-		 AC_MSG_ERROR([scalapack directory provided ($SCALAPACK_ROOT) does not exist]);
+	dnl ScaLAPACK{{{
+
+	dnl NOTE: User should supply path to root directory or libraries, but not both
+	AC_ARG_WITH(
+		[scalapack-dir],
+		AS_HELP_STRING([--with-scalapack-dir=DIR], [ScaLAPACK root directory]),
+		[SCALAPACK_ROOT=${withval}],
+		[SCALAPACK_ROOT="no"]
+	)
+	AC_ARG_WITH(
+		[scalapack-lib],
+		AS_HELP_STRING([--with-scalapack-lib=LIBS], [ScaLAPACK libraries to link to]),
+		[SCALAPACKLIB=${withval}],
+		[SCALAPACKLIB="no"]
+	)
+	AC_MSG_CHECKING([for ScaLAPACK])
+	if test "x${SCALAPACK_ROOT}" == "xno" && test "x${SCALAPACKLIB}" == "xno"; then
+		HAVE_SCALAPACK=no
+		SCALAPACKLIB=""
+	elif test "x${SCALAPACK_ROOT}" != "xno"; then
+		if ! test -d "${SCALAPACK_ROOT}"; then
+			AC_MSG_ERROR([ScaLAPACK directory provided (${SCALAPACK_ROOT}) does not exist!]);
 		fi
 		HAVE_SCALAPACK=yes
-		#SCALAPACKLIB=-L"$SCALAPACK_ROOT/ -lscalapack-openmpi"
-		SCALAPACKLIB=-L"$SCALAPACK_ROOT/ -lscalapack"
-	else if test "x$SCALAPACKLIB" != "xno"; then
+		SCALAPACKLIB="-L${SCALAPACK_ROOT}/lib -lscalapack"
+	elif test "x${SCALAPACKLIB}" != "xno"; then
+		dnl Value of SCALAPACKLIB should be valid here, so no need to set it (as above)
 		HAVE_SCALAPACK=yes
 	else
-	   AC_MSG_ERROR([cannot provide both scalapack dir and scalapack-lib])
-	fi
-	fi
-	fi
-	AC_MSG_RESULT($HAVE_SCALAPACK)
-
-	dnl scalapack headers and libraries
-	if test "x$HAVE_SCALAPACK" = "xyes"; then
-		AC_DEFINE([_HAVE_SCALAPACK_],[1],[with Scalapack in ISSM src])
+		AC_MSG_ERROR([use --with-scalapack-dir or --with-scalapack-lib, but not both])
+	fi
+	AC_MSG_RESULT([${HAVE_SCALAPACK}])
+
+	dnl ScaLAPACK libraries and header files
+	if test "x${HAVE_SCALAPACK}" == "xyes"; then
+		AC_DEFINE([_HAVE_SCALAPACK_], [1], [with ScaLAPACK in ISSM src])
 		AC_SUBST([SCALAPACKLIB])
 	fi
 	dnl }}}
-	dnl blas-lapack{{{
-	AC_ARG_WITH([blas-lapack-dir],
-	  AS_HELP_STRING([--with-blas-lapack-dir=DIR],[blas-lapack root directory]),
-	  [BLASLAPACK_ROOT=$withval],[BLASLAPACK_ROOT="no"])
-
-	dnl Check whether blas-lapack is enabled
-	AC_MSG_CHECKING([for blas-lapack])
-	if test "x$BLASLAPACK_ROOT" = "xno" ; then
+	dnl BLAS/LAPACK{{{
+	AC_ARG_WITH(
+		[blas-lapack-dir],
+		AS_HELP_STRING([--with-blas-lapack-dir=DIR], [BLAS/LAPACK root directory]),
+		[BLASLAPACK_ROOT=$withval],
+		[BLASLAPACK_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for BLAS/LAPACK])
+	if test "x${BLASLAPACK_ROOT}" == "xno" ; then
 		HAVE_BLASLAPACK=no
 	else
 		HAVE_BLASLAPACK=yes
-		if ! test -d "$BLASLAPACK_ROOT"; then
-			AC_MSG_ERROR([blas-lapack directory provided ($BLASLAPACK_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_BLASLAPACK)
-
-	dnl blas-lapack headers and libraries
-	if test "x$HAVE_BLASLAPACK" = "xyes"; then
+		if ! test -d "${BLASLAPACK_ROOT}"; then
+			AC_MSG_ERROR([BLAS/LAPACK directory provided (${BLASLAPACK_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_BLASLAPACK}])
+
+	dnl BLAS/LAPACK libraries and header files
+	if test "x${HAVE_BLASLAPACK}" == "xyes"; then
 		BLASLAPACKINCL=""
 		case "${host_os}" in
-		*cygwin*)
-		  BLASLAPACKLIB="-L`cygpath -m $BLASLAPACK_ROOT` -Wl,libf2cblas.lib  -Wl,libf2clapack.lib"
-		  ;;
-		*linux*)
-			BLASLAPACKLIB="-L${BLASLAPACK_ROOT}/lib"
-			if ls ${BLASLAPACK_ROOT}/lib/liblapack.* 1> /dev/null 2>&1; then
-				BLASLAPACKLIB+=" -llapack -lblas"
-			else
-				BLASLAPACKLIB+=" -lflapack -lfblas"
-			fi
-		;;
-		*darwin*)
-			BLASLAPACKLIB="-L${BLASLAPACK_ROOT}/lib"
-			if ls ${BLASLAPACKLIB}/libflapack.* 1> /dev/null 2>&1; then
-				BLASLAPACKLIB+=" -lflapack -lfblas"
-			else
-				BLASLAPACKLIB+=" -llapack -lblas"
-			fi
-		;;
+			*cygwin*)
+				BLASLAPACKLIB="-L`cygpath -m ${BLASLAPACK_ROOT}` -Wl,libf2cblas.lib  -Wl,libf2clapack.lib"
+			;;
+			*darwin*)
+				BLASLAPACKLIB="-L${BLASLAPACK_ROOT}/lib"
+				if ls ${BLASLAPACK_ROOT}/lib/libopenblas.* 1> /dev/null 2>&1; then
+					BLASLAPACKLIB+=" -lopenblas"
+				elif ls ${BLASLAPACK_ROOT}/lib/liblapack.* 1> /dev/null 2>&1; then
+					BLASLAPACKLIB+=" -llapack -lblas"
+				else
+					BLASLAPACKLIB+=" -lflapack -lfblas"
+				fi
+			;;
+			*linux*)
+				BLASLAPACKLIB="-L${BLASLAPACK_ROOT}/lib"
+				if ls ${BLASLAPACK_ROOT}/lib/libopenblas.* 1> /dev/null 2>&1; then
+					BLASLAPACKLIB+=" -lopenblas"
+				elif ls ${BLASLAPACK_ROOT}/lib/liblapack.* 1> /dev/null 2>&1; then
+					BLASLAPACKLIB+=" -llapack -lblas"
+				else
+					BLASLAPACKLIB+=" -lflapack -lfblas"
+				fi
+			;;
 		esac
-		AC_DEFINE([_HAVE_BLASLAPACK_],[1],[with blas lapack in ISSM src])
+		AC_DEFINE([_HAVE_BLASLAPACK_], [1], [with BLAS/LAPACK in ISSM src])
 		AC_SUBST([BLASLAPACKLIB])
 		AC_SUBST([BLASLAPACKINCL])
 	fi
 	dnl }}}
-	dnl mkl{{{
-		AC_ARG_WITH([mkl-libflags],
-					AS_HELP_STRING([--with-mkl-libflags=LIBS],[mkl libraries to be used]),
-					[MKL_LIBFLAGS=$withval],[MKL_LIBFLAGS="no"])
-
-		  dnl Check whether mkl is enabled
-		  AC_MSG_CHECKING([for mkl])
-		  if test "x$MKL_LIBFLAGS" = "xno" ; then
-				HAVE_MKL=no
-		  else
-				HAVE_MKL=yes
-				MKLLIB="$MKL_LIBFLAGS"
-				AC_DEFINE([_HAVE_MKL_],[1],[with mkl in ISSM src])
-				AC_SUBST([MKLLIB])
-				AC_SUBST([MKLINCL])
-			fi
-			AC_MSG_RESULT($HAVE_MKL)
-	dnl }}}
-	dnl plapack{{{
-	AC_MSG_CHECKING(for plapack)
-
-	AC_ARG_WITH([plapack-lib],
-	  AS_HELP_STRING([--with-plapack-lib = lib],[plapack library]),
-	  [PLAPACK_LIB=$withval],[PLAPACK_LIB=""])
-
-	AC_ARG_WITH([plapack-include],
-			  AS_HELP_STRING([--with-plapack-include = include],
-							 [plapack include ]),
-			  [PLAPACK_INCLUDE=$withval],[PLAPACK_INCLUDE=""])
-
-	if test -n "$PLAPACK_LIB"; then
-		if test -n "$PLAPACK_INCLUDE"; then
-
+	dnl Math Kernel Library (MKL){{{
+	AC_ARG_WITH(
+		[mkl-libflags],
+		AS_HELP_STRING([--with-mkl-libflags=LIBS], [MKL libraries to be used]),
+		[MKL_LIBFLAGS=${withval}],
+		[MKL_LIBFLAGS="no"]
+	)
+	AC_MSG_CHECKING([for MKL])
+	if test "x${MKL_LIBFLAGS}" == "xno"; then
+		HAVE_MKL=no
+	else
+		HAVE_MKL=yes
+		MKLLIB="${MKL_LIBFLAGS}"
+		AC_DEFINE([_HAVE_MKL_], [1], [with MKL in ISSM src])
+		AC_SUBST([MKLLIB])
+		AC_SUBST([MKLINCL])
+	fi
+	AC_MSG_RESULT([${HAVE_MKL}])
+	dnl }}}
+	dnl PlaLAPACK{{{
+
+	dnl TODO: 	Handle user supplying path to root directory *or* individual
+	dnl 		arguments (like ScaLAPACK)
+	dnl
+	AC_MSG_CHECKING(for PlaLAPACK)
+	AC_ARG_WITH(
+		[plapack-lib],
+		AS_HELP_STRING([--with-plapack-lib=<LIB>], [PlaLAPACK library]),
+		[PLAPACK_LIB=${withval}],
+		[PLAPACK_LIB=""]
+	)
+	AC_ARG_WITH(
+		[plapack-include],
+		AS_HELP_STRING([--with-plapack-include=<INC>], [PlaLAPACK include]),
+		[PLAPACK_INCLUDE=${withval}],
+		[PLAPACK_INCLUDE=""]
+	)
+
+	if test -n "${PLAPACK_LIB}"; then
+		if test -n "${PLAPACK_INCLUDE}"; then
 			HAVE_PLAPACK=yes
-			PLAPACKINCL="$PLAPACK_INCLUDE"
-			PLAPACKLIB="$PLAPACK_LIB"
-			AC_DEFINE([_HAVE_PLAPACK_],[1],[with Plapack in ISSM src])
+			PLAPACKINCL="${PLAPACK_INCLUDE}"
+			PLAPACKLIB="${PLAPACK_LIB}"
+			AC_DEFINE([_HAVE_PLAPACK_], [1], [with PlaLAPACK in ISSM src])
 			AC_SUBST([PLAPACKINCL])
 			AC_SUBST([PLAPACKLIB])
@@ -1570,606 +1670,638 @@
 			HAVE_PLAPACK=no
 		fi
-	else
+	elses
 		HAVE_PLAPACK=no
 	fi
-	AC_MSG_RESULT($HAVE_PLAPACK)
-	dnl }}}
-	dnl mumps{{{
-	AC_ARG_WITH([mumps-dir],
-	  AS_HELP_STRING([--with-mumps-dir=DIR],[mumps root directory]),
-	  [MUMPS_ROOT=$withval],[MUMPS_ROOT="no"])
-
-	dnl Check whether mumps is enabled
-	AC_MSG_CHECKING([for mumps])
-	if test "x$MUMPS_ROOT" = "xno" ; then
+	AC_MSG_RESULT([${HAVE_PLAPACK}])
+	dnl }}}
+	dnl MUMPS{{{
+	AC_ARG_WITH(
+		[mumps-dir],
+		AS_HELP_STRING([--with-mumps-dir=DIR], [MUMPS root directory]),
+		[MUMPS_ROOT=${withval}],
+		[MUMPS_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for MUMPS])
+	if test "x${MUMPS_ROOT}" == "xno"; then
 		HAVE_MUMPS=no
 	else
 		HAVE_MUMPS=yes
-		if ! test -d "$MUMPS_ROOT"; then
-			AC_MSG_ERROR([mumps directory provided ($MUMPS_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_MUMPS)
-
-	dnl mumps headers and libraries
-	if test "x$HAVE_MUMPS" == "xyes"; then
-		MUMPSINCL=-I"$MUMPS_ROOT/include"
-		if test "$PETSC_MAJOR" = "2" ; then
-			MUMPSLIB=-L"$MUMPS_ROOT/lib "
+		if ! test -d "${MUMPS_ROOT}"; then
+			AC_MSG_ERROR([MUMPS directory provided (${MUMPS_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_MUMPS}])
+
+	dnl MUMPS libraries and header files
+	if test "x${HAVE_MUMPS}" == "xyes"; then
+		MUMPSINCL="-I${MUMPS_ROOT}/include"
+		if test "x${MUMPS_ROOT}" == "x${PETSC_ROOT}"; then
+			if test "x${PETSC_MAJOR}" == "x2"; then
+				MUMPSLIB="-L${MUMPS_ROOT}/lib "
+			else
+				MUMPSLIB="-L${MUMPS_ROOT}/lib -ldmumps -lcmumps -lmumps_common -lpord -lparmetis -lzmumps -lmetis"
+			fi
 		else
-			MUMPSLIB=-L"$MUMPS_ROOT/lib -ldmumps -lcmumps  -lmumps_common -lpord -lparmetis -lzmumps -lmetis"
-			dnl MUMPSLIB=-L"$MUMPS_ROOT/lib "
-		fi
-		AC_DEFINE([_HAVE_MUMPS_],[1],[with Mumps in ISSM src])
+			MUMPSLIB="-L${MUMPS_ROOT}/lib -ldmumps -lmumps_common -lpord"
+		fi
+		AC_DEFINE([_HAVE_MUMPS_], [1], [with MUMPS in ISSM src])
 		AC_SUBST([MUMPSINCL])
 		AC_SUBST([MUMPSLIB])
 	fi
-	AM_CONDITIONAL([MUMPS], [test x$HAVE_MUMPS = xyes])
-	dnl }}}
-	dnl mumps2{{{
-	if test "x$HAVE_MUMPS" != "xyes"; then
-	AC_MSG_CHECKING(for mumps2 (stand alone))
-
-	AC_ARG_WITH([mumps2-include],
-	  AS_HELP_STRING([--with-mumps2-include=DIR],[mumps2 include directory, necessary for parallel build]),
-	  [MUMPS_INCLUDE=$withval],[MUMPS_INCLUDE=""])
-
-	AC_ARG_WITH([mumps2-libflags],
-	  AS_HELP_STRING([--with-mumps2-libflags=LIBS],[mumps2 libraries to be used, necessary for parallel build]),
-	  [MUMPS_LIBFLAGS=$withval],[MUMPS_LIBFLAGS=""])
-
-
-	if test -z "$MUMPS_INCLUDE" ; then
-		HAVE_MUMPS=no
-	else
-		HAVE_MUMPS=yes
-
-		if test -z "$MUMPS_LIBDIR"; then
-			MUMPSINCL=-I"$MUMPS_INCLUDE"
-			MUMPSLIB="$MUMPS_LIBFLAGS"
+	AM_CONDITIONAL([MUMPS], [test "x${HAVE_MUMPS}" == "xyes"])
+	dnl }}}
+	dnl MUMPS2{{{
+	if test "x${HAVE_MUMPS}" != "xyes"; then
+		AC_MSG_CHECKING(for MUMPS2 (standalone))
+		AC_ARG_WITH(
+			[mumps2-include],
+			AS_HELP_STRING([--with-mumps2-include=DIR], [MUMPS2 include directory, necessary for parallel build]),
+			[MUMPS_INCLUDE=${withval}],
+			[MUMPS_INCLUDE=""]
+		)
+		AC_ARG_WITH(
+			[mumps2-libflags],
+			AS_HELP_STRING([--with-mumps2-libflags=LIBS], [MUMPS2 libraries to be used, necessary for parallel build]),
+			[MUMPS_LIBFLAGS=${withval}],
+			[MUMPS_LIBFLAGS=""]
+		)
+		if test -z "${MUMPS_INCLUDE}"; then
+			HAVE_MUMPS=no
 		else
-			MUMPSINCL=-I"$MUMPS_INCLUDE"
-			MUMPSLIB="-L$MUMPS_LIBDIR $MUMPS_LIBFLAGS"
-		fi
-		AC_DEFINE([_HAVE_MUMPS_],[1],[with MUMPS])
-		AC_SUBST([MUMPSINCL])
-		AC_SUBST([MUMPSLIB])
-	fi
-	AM_CONDITIONAL([MUMPS], [test x$HAVE_MUMPS = xyes])
-	AC_MSG_RESULT($HAVE_MUMPS)
-
-	fi
-	dnl }}}
-	dnl blacs{{{
-	AC_ARG_WITH([blacs-dir],
-		AS_HELP_STRING([--with-blacs-dir=DIR],[blacs root directory]),
-			  [BLACS_ROOT=$withval],[BLACS_ROOT="no"])
-
-	dnl Check whether blacs is enabled
-	AC_MSG_CHECKING([for blacs])
-	if test "x$BLACS_ROOT" = "xno" ; then
+			HAVE_MUMPS=yes
+
+			if test -z "${MUMPS_LIBDIR}"; then
+				MUMPSINCL="-I${MUMPS_INCLUDE}"
+				MUMPSLIB="${MUMPS_LIBFLAGS}"
+			else
+				MUMPSINCL="-I${MUMPS_INCLUDE}"
+				MUMPSLIB="-L${MUMPS_LIBDIR} ${MUMPS_LIBFLAGS}"
+			fi
+			AC_DEFINE([_HAVE_MUMPS_], [1], [with MUMPS])
+			AC_SUBST([MUMPSINCL])
+			AC_SUBST([MUMPSLIB])
+		fi
+		AM_CONDITIONAL([MUMPS], [test "x${HAVE_MUMPS}" == "xyes"])
+		AC_MSG_RESULT([${HAVE_MUMPS}])
+	fi
+	dnl }}}
+	dnl BLACS{{{
+	AC_ARG_WITH(
+		[blacs-dir],
+		AS_HELP_STRING([--with-blacs-dir=DIR], [BLACS root directory]),
+		[BLACS_ROOT=${withval}],
+		[BLACS_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for BLACS])
+	if test "x${BLACS_ROOT}" == "xno"; then
 		HAVE_BLACS=no
 	else
 		HAVE_BLACS=yes
-		if ! test -d "$BLACS_ROOT"; then
-			AC_MSG_ERROR([blacs directory provided ($BLACS_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_BLACS)
-
-	dnl blacs headers and libraries
-	if test "x$HAVE_BLACS" == "xyes"; then
+		if ! test -d "${BLACS_ROOT}"; then
+			AC_MSG_ERROR([BLACS directory provided (${BLACS_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_BLACS}])
+
+	dnl BLACS libraries and header files
+	if test "x${HAVE_BLACS}" == "xyes"; then
 		BLACSINCL=""
-		BLACSLIB=-L"$BLACS_ROOT/ -lblacs"
-		AC_DEFINE([_HAVE_BLACS_],[1],[with Blacs in ISSM src])
+		BLACSLIB="-L${BLACS_ROOT} -lblacs"
+		AC_DEFINE([_HAVE_BLACS_], [1], [with BLACS in ISSM src])
 		AC_SUBST([BLACSINCL])
 		AC_SUBST([BLACSLIB])
 	fi
 	dnl }}}
-	dnl hypre{{{
-	AC_ARG_WITH([hypre-dir],
-	  AS_HELP_STRING([--with-hypre-dir=DIR],[hypre root directory]),
-			  [HYPRE_ROOT=$withval],[HYPRE_ROOT="no"])
-
-	dnl Check whether hypre is enabled
-	AC_MSG_CHECKING([for hypre])
-	if test "x$HYPRE_ROOT" = "xno" ; then
+	dnl HYPRE{{{
+	AC_ARG_WITH(
+		[hypre-dir],
+		AS_HELP_STRING([--with-hypre-dir=DIR], [HYPRE root directory]),
+		[HYPRE_ROOT=${withval}],
+		[HYPRE_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for HYPRE])
+	if test "x${HYPRE_ROOT}" == "xno"; then
 		HAVE_HYPRE=no
 	else
 		HAVE_HYPRE=yes
-		if ! test -d "$HYPRE_ROOT"; then
-			AC_MSG_ERROR([hypre directory provided ($HYPRE_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_HYPRE)
-
-	dnl hypre headers and libraries
-	if test "x$HAVE_HYPRE" == "xyes"; then
+		if ! test -d "${HYPRE_ROOT}"; then
+			AC_MSG_ERROR([HYPRE directory provided (${HYPRE_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_HYPRE}])
+
+	dnl HYPRE libraries and header files
+	if test "x${HAVE_HYPRE}" == "xyes"; then
 		HYPREINCL=""
-		HYPRELIB=-L"$HYPRE_ROOT/lib -lHYPRE"
-		AC_DEFINE([_HAVE_HYPRE_],[1],[with Hypre in ISSM src])
+		HYPRELIB="-L${HYPRE_ROOT}/lib -lHYPRE"
+		AC_DEFINE([_HAVE_HYPRE_], [1], [with HYPRE in ISSM src])
 		AC_SUBST([HYPREINCL])
 		AC_SUBST([HYPRELIB])
 	fi
 	dnl }}}
-	dnl prometheus{{{
-	AC_ARG_WITH([prometheus-dir],
-				AS_HELP_STRING([--with-prometheus-dir=DIR],[prometheus root directory]),
-				[PROMETHEUS_ROOT=$withval],[PROMETHEUS_ROOT="no"])
-
-		dnl Check whether prometheus is enabled
-		AC_MSG_CHECKING([for prometheus])
-		if test "x$PROMETHEUS_ROOT" = "xno" ; then
-			HAVE_PROMETHEUS=no
-		else
-			HAVE_PROMETHEUS=yes
-			if ! test -d "$PROMETHEUS_ROOT"; then
-				AC_MSG_ERROR([prometheus directory provided ($PROMETHEUS_ROOT) does not exist]);
-			fi
-		fi
-		AC_MSG_RESULT($HAVE_PROMETHEUS)
-
-		dnl prometheus headers and libraries
-		if test "x$HAVE_PROMETHEUS" == "xyes"; then
-			 PROMETHEUSINCL=-I"$PROMETHEUS_ROOT/include"
-			 PROMETHEUSLIB=-L"$PROMETHEUS_ROOT/lib -lpromfei -lprometheus -lparmetis"
-			 AC_DEFINE([_HAVE_PROMETHEUS_],[1],[with Prometheus in ISSM src])
-			 AC_SUBST([PROMETHEUSINCL])
-			 AC_SUBST([PROMETHEUSLIB])
-	   fi
-		dnl }}}
-	dnl semic{{{
-	AC_ARG_WITH([semic-dir],
-		AS_HELP_STRING([--with-semic-dir=DIR], [Semic root directory.]),
-		[SEMIC_ROOT=$withval],[SEMIC_ROOT="no"])
-
-	dnl Check whether semic is enabled
-	AC_MSG_CHECKING([for semic])
-	if test "x$SEMIC_ROOT" = "xno" ; then
+	dnl Prometheus{{{
+	AC_ARG_WITH(
+		[prometheus-dir],
+		AS_HELP_STRING([--with-prometheus-dir=DIR], [Prometheus root directory]),
+		[PROMETHEUS_ROOT=${withval}],
+		[PROMETHEUS_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for Prometheus])
+	if test "x${PROMETHEUS_ROOT}" == "xno"; then
+		HAVE_PROMETHEUS=no
+	else
+		HAVE_PROMETHEUS=yes
+		if ! test -d "${PROMETHEUS_ROOT}"; then
+			AC_MSG_ERROR([Prometheus directory provided (${PROMETHEUS_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_PROMETHEUS}])
+
+	dnl Prometheus libraries and header files
+	if test "x${HAVE_PROMETHEUS}" == "xyes"; then
+		PROMETHEUSINCL="-I${PROMETHEUS_ROOT}/include"
+		PROMETHEUSLIB="-L${PROMETHEUS_ROOT}/lib -lpromfei -lprometheus -lparmetis"
+		AC_DEFINE([_HAVE_PROMETHEUS_], [1], [with Prometheus in ISSM src])
+		AC_SUBST([PROMETHEUSINCL])
+		AC_SUBST([PROMETHEUSLIB])
+	fi
+	dnl }}}
+	dnl SEMIC{{{
+	AC_ARG_WITH(
+		[semic-dir],
+		AS_HELP_STRING([--with-semic-dir=DIR], [SEMIC root directory]),
+		[SEMIC_ROOT=${withval}],
+		[SEMIC_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for SEMIC])
+	if test "x${SEMIC_ROOT}" == "xno"; then
 		HAVE_SEMIC=no
 	else
 		HAVE_SEMIC=yes
-		if ! test -d "$SEMIC_ROOT"; then
-			AC_MSG_ERROR([semic directory provided ($SEMIC_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_SEMIC)
-
-	dnl semic headers and libraries
-	if test "x$HAVE_SEMIC" == "xyes"; then
-		SEMICINCL="-I$SEMIC_ROOT/"
-		AC_DEFINE([_HAVE_SEMIC_],[1],[with semic in ISSM src])
-		SEMICLIB="$SEMIC_ROOT/libsurface_physics.a $SEMIC_ROOT/libutils.a"
+		if ! test -d "${SEMIC_ROOT}"; then
+			AC_MSG_ERROR([SEMIC directory provided (${SEMIC_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SEMIC}])
+
+	dnl SEMIC libraries and header files
+	if test "x${HAVE_SEMIC}" == "xyes"; then
+		SEMICINCL="-I${SEMIC_ROOT}"
+		AC_DEFINE([_HAVE_SEMIC_], [1], [with SEMIC in ISSM src])
+		SEMICLIB="-L${SEMIC_ROOT} -lsurface_physics -lutils"
 		AC_SUBST([SEMICLIB])
 		AC_SUBST([SEMICINCL])
 	fi
-	AM_CONDITIONAL([SEMIC],[test x$HAVE_SEMIC = xyes])
-	dnl }}}
-dnl spai{{{
-	AC_ARG_WITH([spai-dir],
-				AS_HELP_STRING([--with-spai-dir=DIR],[spai root directory]),
-				[SPAI_ROOT=$withval],[SPAI_ROOT="no"])
-
-		dnl Check whether spai is enabled
-		AC_MSG_CHECKING([for spai])
-		if test "x$SPAI_ROOT" = "xno" ; then
-			HAVE_SPAI=no
-		else
-			HAVE_SPAI=yes
-			if ! test -d "$SPAI_ROOT"; then
-				AC_MSG_ERROR([spai directory provided ($SPAI_ROOT) does not exist]);
-			fi
-		fi
-		AC_MSG_RESULT($HAVE_SPAI)
-
-		dnl spai headers and libraries
-		if test "x$HAVE_SPAI" == "xyes"; then
-			SPAIINCL=-I"$SPAI_ROOT/include"
-			SPAILIB=-L"$SPAI_ROOT/lib -lspai"
-			AC_DEFINE([_HAVE_SPAI_],[1],[with Spai in ISSM src])
-			AC_SUBST([SPAIINCL])
-			AC_SUBST([SPAILIB])
-		fi
-	  dnl }}}
-dnl superlu{{{
-	AC_ARG_WITH([superlu-dir],
-				AS_HELP_STRING([--with-superlu-dir=DIR],[superlu root directory]),
-				[SUPERLU_ROOT=$withval],[SUPERLU_ROOT="no"])
-
-	dnl Check whether superlu is enabled
-	AC_MSG_CHECKING([for superlu])
-	if test "x$SUPERLU_ROOT" = "xno" ; then
+	AM_CONDITIONAL([SEMIC], [test "x${HAVE_SEMIC}" == "xyes"])
+	dnl }}}
+	dnl SPAI{{{
+	AC_ARG_WITH(
+		[spai-dir],
+		AS_HELP_STRING([--with-spai-dir=DIR], [SPAI root directory]),
+		[SPAI_ROOT=${withval}],
+		[SPAI_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for SPAI])
+	if test "x${SPAI_ROOT}" == "xno"; then
+		HAVE_SPAI=no
+	else
+		HAVE_SPAI=yes
+		if ! test -d "${SPAI_ROOT}"; then
+			AC_MSG_ERROR([SPAI directory provided (${SPAI_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SPAI}])
+
+	dnl SPAI libraries and header files
+	if test "x${HAVE_SPAI}" == "xyes"; then
+		SPAIINCL="-I${SPAI_ROOT}/include"
+		SPAILIB="-L${SPAI_ROOT}/lib -lspai"
+		AC_DEFINE([_HAVE_SPAI_], [1], [with SPAI in ISSM src])
+		AC_SUBST([SPAIINCL])
+		AC_SUBST([SPAILIB])
+	fi
+	dnl }}}
+	dnl SuperLU{{{
+	AC_ARG_WITH(
+		[superlu-dir],
+		AS_HELP_STRING([--with-superlu-dir=DIR], [SuperLU root directory]),
+		[SUPERLU_ROOT=${withval}],
+		[SUPERLU_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for SuperLU])
+	if test "x${SUPERLU_ROOT}" == "xno"; then
 		HAVE_SUPERLU=no
 	else
 		HAVE_SUPERLU=yes
-		if ! test -d "$SUPERLU_ROOT"; then
-			AC_MSG_ERROR([superlu directory provided ($SUPERLU_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_SUPERLU)
-
-	dnl superlu headers and libraries
-	if test "x$HAVE_SUPERLU" == "xyes"; then
-		  SUPERLUINCL=-I"$SUPERLU_ROOT/include"
-		  SUPERLULIB=-L"$SUPERLU_ROOT/lib -lsuperlu_dist"
-		  AC_DEFINE([_HAVE_SUPERLU_],[1],[with Superlu in ISSM src])
-		  AC_SUBST([SUPERLUINCL])
-		  AC_SUBST([SUPERLULIB])
-	 fi
-	 dnl }}}
-dnl spooles{{{
-	AC_ARG_WITH([spooles-dir],
-				AS_HELP_STRING([--with-spooles-dir=DIR],[spooles root directory]),
-				[SPOOLES_ROOT=$withval],[SPOOLES_ROOT="no"])
-
-	dnl Check whether spooles is enabled
-	AC_MSG_CHECKING([for spooles])
-	if test "x$SPOOLES_ROOT" = "xno" ; then
+		if ! test -d "${SUPERLU_ROOT}"; then
+			AC_MSG_ERROR([SuperLU directory provided (${SUPERLU_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SUPERLU}])
+
+	dnl SuperLU libraries and header files
+	if test "x${HAVE_SUPERLU}" == "xyes"; then
+		SUPERLUINCL="-I${SUPERLU_ROOT}/include"
+		SUPERLULIB="-L${SUPERLU_ROOT}/lib -lsuperlu_dist"
+		AC_DEFINE([_HAVE_SUPERLU_], [1], [with SuperLU in ISSM src])
+		AC_SUBST([SUPERLUINCL])
+		AC_SUBST([SUPERLULIB])
+	fi
+	dnl }}}
+	dnl SPOOLES{{{
+	AC_ARG_WITH(
+		[spooles-dir],
+		AS_HELP_STRING([--with-spooles-dir=DIR], [SPOOLES root directory]),
+		[SPOOLES_ROOT=${withval}],
+		[SPOOLES_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for SPOOLES])
+	if test "x${SPOOLES_ROOT}" == "xno"; then
 		HAVE_SPOOLES=no
 	else
 		HAVE_SPOOLES=yes
-		if ! test -d "$SPOOLES_ROOT"; then
-			AC_MSG_ERROR([spooles directory provided ($SPOOLES_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_SPOOLES)
-
-	dnl spooles headers and libraries
-	if test "x$HAVE_SPOOLES" == "xyes"; then
-		  SPOOLESINCL=-I"$SPOOLES_ROOT/include"
-		  SPOOLESLIB=-L"$SPOOLES_ROOT/lib -lspooles"
-		  AC_DEFINE([_HAVE_SPOOLES_],[1],[with Spooles in ISSM src])
-		  AC_SUBST([SPOOLESINCL])
-		  AC_SUBST([SPOOLESLIB])
-	 fi
-	 dnl }}}
-dnl pastix{{{
-	AC_ARG_WITH([pastix-dir],
-				AS_HELP_STRING([--with-pastix-dir=DIR],[pastix root directory]),
-				[PASTIX_ROOT=$withval],[PASTIX_ROOT="no"])
-
-	dnl Check whether pastix is enabled
-	AC_MSG_CHECKING([for pastix])
-	if test "x$PASTIX_ROOT" = "xno" ; then
+		if ! test -d "${SPOOLES_ROOT}"; then
+			AC_MSG_ERROR([SPOOLES directory provided (${SPOOLES_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SPOOLES}])
+
+	dnl SPOOLES libraries and header files
+	if test "x${HAVE_SPOOLES}" == "xyes"; then
+		SPOOLESINCL="-I${SPOOLES_ROOT}/include"
+		SPOOLESLIB="-L${SPOOLES_ROOT}/lib -lspooles"
+		AC_DEFINE([_HAVE_SPOOLES_], [1], [with SPOOLES in ISSM src])
+		AC_SUBST([SPOOLESINCL])
+		AC_SUBST([SPOOLESLIB])
+	fi
+	dnl }}}
+	dnl PaStiX{{{
+	AC_ARG_WITH(
+		[pastix-dir],
+		AS_HELP_STRING([--with-pastix-dir=DIR], [PaStiX root directory]),
+		[PASTIX_ROOT=${withval}],
+		[PASTIX_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for PaStiX])
+	if test "x${PASTIX_ROOT}" == "xno"; then
 		HAVE_PASTIX=no
 	else
 		HAVE_PASTIX=yes
-		if ! test -d "$PASTIX_ROOT"; then
-			AC_MSG_ERROR([pastix directory provided ($PASTIX_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_PASTIX)
-
-	dnl pastix headers and libraries
-	if test "x$HAVE_PASTIX" == "xyes"; then
-		  PASTIXINCL=-I"$PASTIX_ROOT/include"
-		  PASTIXLIB=-L"$PASTIX_ROOT/lib -lpastix_XXbit_mpi_smp_nobubble_int32_simple_real_scotch_i686_pc_linux -lptscotch -lptscotcherr -lpastix"
-		  AC_DEFINE([_HAVE_PASTIX_],[1],[with Pastix in ISSM src])
-		  AC_SUBST([PASTIXINCL])
-		  AC_SUBST([PASTIXLIB])
-  fi
-  dnl }}}
+		if ! test -d "${PASTIX_ROOT}"; then
+			AC_MSG_ERROR([PaStiX directory provided (${PASTIX_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_PASTIX}])
+
+	dnl PaStiX libraries and header files
+	if test "x${HAVE_PASTIX}" == "xyes"; then
+		PASTIXINCL="-I${PASTIX_ROOT}/include"
+		PASTIXLIB="-L${PASTIX_ROOT}/lib -lpastix_XXbit_mpi_smp_nobubble_int32_simple_real_scotch_i686_pc_linux -lptscotch -lptscotcherr -lpastix"
+		AC_DEFINE([_HAVE_PASTIX_], [1], [with PaStiX in ISSM src])
+		AC_SUBST([PASTIXINCL])
+		AC_SUBST([PASTIXLIB])
+	fi
+	dnl }}}
+	dnl }}}
 	dnl ml{{{
-	AC_ARG_WITH([ml-dir],
-	  AS_HELP_STRING([--with-ml-dir=DIR],[ml root directory]),
-			  [ML_ROOT=$withval],[ML_ROOT="no"])
-
-	dnl Check whether ml is enabled
+	AC_ARG_WITH(
+		[ml-dir],
+		AS_HELP_STRING([--with-ml-dir=DIR],[ml root directory]),
+		[ML_ROOT=$withval],
+		[ML_ROOT="no"]
+	)
 	AC_MSG_CHECKING([for ml])
-	if test "x$ML_ROOT" = "xno" ; then
+	if test "x${ML_ROOT}" == "xno"; then
 		HAVE_ML=no
 	else
 		HAVE_ML=yes
-		if ! test -d "$ML_ROOT"; then
-			AC_MSG_ERROR([ml directory provided ($ML_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_ML)
-
-	dnl ml headers and libraries
-	if test "x$HAVE_ML" == "xyes"; then
-		MLINCL=-I"$ML_ROOT/include"
-		MLLIB=-L"$ML_ROOT/lib -lml"
-		AC_DEFINE([_HAVE_ML_],[1],[with Blacs in ISSM src])
+		if ! test -d "${ML_ROOT}"; then
+			AC_MSG_ERROR([ml directory provided (${ML_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_ML}])
+
+	dnl ml libraries and header files
+	if test "x${HAVE_ML}" == "xyes"; then
+		MLINCL=-I"${ML_ROOT}/include"
+		MLLIB=-L"${ML_ROOT}/lib -lml"
+		AC_DEFINE([_HAVE_ML_], [1], [with ml in ISSM src])
 		AC_SUBST([MLINCL])
 		AC_SUBST([MLLIB])
 	fi
 	dnl }}}
-	dnl umfpack{{{
-		AC_ARG_WITH([umfpack-dir],
-		  AS_HELP_STRING([--with-umfpack-dir=DIR],[UMFPACK root directory]),
-					[UMFPACK_ROOT=$withval],[UMFPACK_ROOT="no"])
-
-	dnl Check whether umfpack is enabled
-	AC_MSG_CHECKING([for umfpack])
-	if test "x$UMFPACK_ROOT" = "xno" ; then
+	dnl UMFPACK{{{
+	AC_ARG_WITH(
+		[umfpack-dir],
+		AS_HELP_STRING([--with-umfpack-dir=DIR], [UMFPACK root directory]),
+		[UMFPACK_ROOT=${withval}],
+		[UMFPACK_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for UMFPACK])
+	if test "x${UMFPACK_ROOT}" == "xno"; then
 		HAVE_UMFPACK=no
 	else
 		HAVE_UMFPACK=yes
-		if ! test -d "$UMFPACK_ROOT"; then
-			AC_MSG_ERROR([umfpack directory provided ($UMFPACK_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_UMFPACK)
-
-	dnl umfpack headers and libraries
-	if test "x$HAVE_UMFPACK" == "xyes"; then
+		if ! test -d "${UMFPACK_ROOT}"; then
+			AC_MSG_ERROR([UMFPACK directory provided (${UMFPACK_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_UMFPACK}])
+
+	dnl UMFPACK libraries and header files
+	if test "x${HAVE_UMFPACK}" == "xyes"; then
 		UMFPACKINCL=""
-		UMFPACKLIB=-L"$UMFPACK_ROOT/lib -lumfpack -lumfpack.5.5.1"
-		AC_DEFINE([_HAVE_UMFPACK_],[1],[with UMFPACK in ISSM src])
+		UMFPACKLIB="-L${UMFPACK_ROOT}/lib -lumfpack -lumfpack.5.5.1"
+		AC_DEFINE([_HAVE_UMFPACK_], [1], [with UMFPACK in ISSM src])
 		AC_SUBST([UMFPACKINCL])
 		AC_SUBST([UMFPACKLIB])
 	fi
 	dnl }}}
-dnl math{{{
-	AC_MSG_CHECKING(for math library)
-	AC_ARG_WITH([math-lib],
-	  AS_HELP_STRING([--with-math-lib = otions],[math options, for ex: "/usr/lib/libm.a]),
-	  [MATH_LIB=$withval],[MATH_LIB=""])
-
-	dnl check that --with-math-lib may have been provided
-	if test -n "$MATH_LIB" ; then
+	dnl libm (GNU math library){{{
+	AC_MSG_CHECKING(for libm)
+	AC_ARG_WITH(
+		[math-lib],
+		AS_HELP_STRING([--with-math-lib=LIB], [libm (GNU math library) to use]),
+		[MATH_LIB=${withval}],
+		[MATH_LIB=""]
+	)
+	if test -n "${MATH_LIB}"; then
 		HAVE_MATH=yes
-		MATHLIB="$MATH_LIB"
-		AC_DEFINE([_HAVE_MATH_],[1],[with MATH in ISSM src])
+		MATHLIB="${MATH_LIB}"
+		AC_DEFINE([_HAVE_MATH_], [1], [with libm (GNU math library) in ISSM src])
 		AC_SUBST([MATHLIB])
 	fi
-	AC_MSG_RESULT(done)
-	dnl }}}
-	dnl math77{{{
-		AC_ARG_WITH([math77-dir],
-					AS_HELP_STRING([--with-math77-dir=DIR], [math77 root directory.]),
-					[MATH77_ROOT=$withval],[MATH77_ROOT="no"])
-
-	dnl Check whether math77 is enabled
-	AC_MSG_CHECKING([for math77])
-	if test "x$MATH77_ROOT" = "xno" ; then
+	AC_MSG_RESULT([done])
+	dnl }}}
+	dnl MATH77{{{
+	AC_ARG_WITH(
+		[math77-dir],
+		AS_HELP_STRING([--with-math77-dir=DIR], [MATH77 root directory]),
+		[MATH77_ROOT=${withval}],
+		[MATH77_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for MATH77])
+	if test "x${MATH77_ROOT}" == "xno"; then
 		HAVE_MATH77=no
 	else
 		HAVE_MATH77=yes
-		if ! test -d "$MATH77_ROOT"; then
-			AC_MSG_ERROR([math77 directory provided ($MATH77_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_MATH77)
-
-	dnl math77 headers and libraries
-	if test "x$HAVE_MATH77" == "xyes"; then
-		MATH77LIB="-L$MATH77_ROOT/ -lmath77"
-		AC_DEFINE([_HAVE_MATH77_],[1],[with math77 in ISSM src])
+		if ! test -d "${MATH77_ROOT}"; then
+			AC_MSG_ERROR([MATH77 directory provided (${MATH77_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_MATH77}])
+
+	dnl MATH77 libraries and header files
+	if test "x${HAVE_MATH77}" == "xyes"; then
+		MATH77LIB="-L${MATH77_ROOT} -lmath77"
+		AC_DEFINE([_HAVE_MATH77_], [1], [with MATH77 in ISSM src])
 		AC_SUBST([MATH77LIB])
-   fi
-	dnl }}}
-	dnl fortran{{{
-	AC_ARG_WITH([fortran],
-		AS_HELP_STRING([--with-fortran = YES], [do we compile fortran code (default is yes)]),
-		[FORTRAN=$withval],[FORTRAN=yes])
-	AC_MSG_CHECKING(for fortran compilation)
-	if test "x$FORTRAN" = "xyes"; then
-		dnl defaults
+	fi
+	dnl }}}
+	dnl Fortran{{{
+	AC_ARG_WITH(
+		[fortran],
+		AS_HELP_STRING([--with-fortran=YES], [do we compile Fortran code (default: yes)]),
+		[FORTRAN=${withval}],
+		[FORTRAN=yes]
+	)
+	AC_MSG_CHECKING(for Fortran compilation)
+	if test "x${FORTRAN}" == "xyes"; then
 		HAVE_FORTRAN=yes
-		AC_DEFINE([_HAVE_FORTRAN_],[1],[with fortran capability])
+		AC_DEFINE([_HAVE_FORTRAN_], [1], [with Fortran capability])
 	else
 		HAVE_FORTRAN=no
 	fi
-	AM_CONDITIONAL([FORTRAN], [test x$FORTRAN = xyes])
-	AC_MSG_RESULT($FORTRAN)
-
-	if test "x$FORTRAN" = "xyes"; then
-		dnl fortran library  option
-		AC_MSG_CHECKING(for fortran library)
-		AC_ARG_WITH([fortran-lib],
-		  AS_HELP_STRING([--with-fortran-lib = options],[fortran options, for ex: "/usr/lib/gfortran.a]),
-			[FORTRAN_LIB=$withval],[FORTRAN_LIB=""])
-
-		dnl check that --with-fortran-lib may have been provided
-		if test -n "$FORTRAN_LIB" ; then
-			dnl check that library provided EXISTS!
-		   FORTRAN_DIR=$(echo $FORTRAN_LIB | sed -e "s/-L//g" | awk '{print $[1]}')
-			if test -d "$FORTRAN_DIR" || test -f "$FORTRAN_DIR"; then
-				FORTRANLIB="$FORTRAN_LIB"
-				AC_DEFINE([_HAVE_FORTRAN_],[1],[with FORTRAN in ISSM src])
+	AM_CONDITIONAL([FORTRAN], [test "x${FORTRAN}" == "xyes"])
+	AC_MSG_RESULT([${FORTRAN}])
+
+	if test "x${FORTRAN}" == "xyes"; then
+		dnl Fortran library
+		AC_MSG_CHECKING([for Fortran library])
+		AC_ARG_WITH(
+			[fortran-lib],
+			AS_HELP_STRING([--with-fortran-lib=LIB], [Fortran library to use (and, if needed, libraries on which it depends)]),
+			[FORTRAN_LIB=${withval}],
+			[FORTRAN_LIB=""]
+		)
+		if test -n "${FORTRAN_LIB}"; then
+			FORTRAN_DIR=$(echo ${FORTRAN_LIB} | sed -e "s/-L//g" | awk '{print $[1]}')
+			if test -d "${FORTRAN_DIR}" || test -f "${FORTRAN_DIR}"; then
+				FORTRANLIB="${FORTRAN_LIB}"
+				AC_DEFINE([_HAVE_FORTRAN_], [1], [with Fortran library in ISSM src])
 				AC_SUBST([FORTRANLIB])
 			else
-			 if test "x$HAVE_MPI" = "xyes"; then
-				FORTRANLIB=$(mpif77 -print-file-name="libgfortran.a")
-				if test -f "$FORTRANLIB"; then
-					 AC_MSG_ERROR([fortran library provided ($FORTRAN_LIB) does not exist, MPI suggests the following library: $FORTRANLIB]);
-				fi
-			 fi
-				AC_MSG_ERROR([fortran library provided ($FORTRAN_LIB) does not exist!]);
+				if test "x${HAVE_MPI}" == "xyes"; then
+					MPI_REC_FORTRAN_LIB=$(mpif77 -print-file-name="libgfortran.a")
+					if test -f "${FORTRANLIB}"; then
+						AC_MSG_ERROR([Fortran library provided (${FORTRAN_LIB}) does not exist! MPI suggests the following library: ${MPI_REC_FORTRAN_LIB}]);
+					fi
+			 	fi
+				AC_MSG_ERROR([Fortran library provided (${FORTRAN_LIB}) does not exist!]);
 			fi
 		fi
-		AC_MSG_RESULT(done)
-	fi
-	dnl }}}
-	dnl graphics{{{
-	AC_MSG_CHECKING(for graphics library)
-	AC_ARG_WITH([graphics-lib],
-	  AS_HELP_STRING([--with-graphics-lib = options],[graphics options, for ex: "/usr/X11/lib/libX11.a]),
-	  [GRAPHICS_LIB=$withval],[GRAPHICS_LIB=""])
-
-	dnl check that --with-graphics-lib may have been provided
-	if test -n "$GRAPHICS_LIB" ; then
-		dnl check that library provided EXISTS!
-		GRAPHICS_DIR=$(echo $GRAPHICS_LIB | sed -e "s/-L//g" | awk '{print $[1]}')
-		if test -d "$GRAPHICS_DIR" || test -f "$GRAPHICS_DIR"; then
+		AC_MSG_RESULT([done])
+	fi
+	dnl }}}
+	dnl Xlib (graphics library){{{
+	AC_MSG_CHECKING([for Xlib (graphics library)])
+	AC_ARG_WITH(
+		[graphics-lib],
+		AS_HELP_STRING([--with-graphics-lib=options], [Xlib (graphics library) to use]),
+		[GRAPHICS_LIB=${withval}],
+		[GRAPHICS_LIB=""]
+	)
+	if test -n "${GRAPHICS_LIB}"; then
+		GRAPHICS_DIR=$(echo ${GRAPHICS_LIB} | sed -e "s/-L//g" | awk '{print $[1]}')
+		if test -d "${GRAPHICS_DIR}" || test -f "${GRAPHICS_DIR}"; then
 			HAVE_GRAPHICS=yes
-			GRAPHICSLIB="$GRAPHICS_LIB"
-			AC_DEFINE([_HAVE_GRAPHICS_],[1],[with GRAPHICS in ISSM src])
+			GRAPHICSLIB="${GRAPHICS_LIB}"
+			AC_DEFINE([_HAVE_GRAPHICS_], [1], [with Xlib (graphics library) in ISSM src])
 			AC_SUBST([GRAPHICSLIB])
 		else
-			if test -f "$PETSC_ROOT/conf/petscvariables"; then
-				GRAPHICSLIB=$(cat $PETSC_ROOT/conf/petscvariables | grep X_LIB)
-				AC_MSG_ERROR([graphics library provided ($GRAPHICS_LIB) does not exist, PETSc suggests the following library: $GRAPHICSLIB]);
+			if test -f "${PETSC_ROOT}/conf/petscvariables"; then
+				PETSC_REC_GRAPHICS_LIB=$(cat ${PETSC_ROOT}/conf/petscvariables | grep X_LIB)
+				AC_MSG_ERROR([Xlib (graphics library) provided (${GRAPHICS_LIB}) does not exist! PETSc suggests the following library: ${PETSC_REC_GRAPHICS_LIB}]);
 			fi
-			AC_MSG_ERROR([graphics library provided ($GRAPHICS_LIB$) does not exist!]);
-		fi
-	fi
-	AC_MSG_RESULT(done)
-	dnl }}}
-	dnl meteoio{{{
-	AC_ARG_WITH([meteoio-dir],
-	  AS_HELP_STRING([--with-meteoio-dir=DIR], [use meteoio in conjunction with snowpack model.]),
-	  [METEOIO_ROOT=$withval],[METEOIO_ROOT="no"])
-
-	dnl Check whether meteoio is enabled
-	AC_MSG_CHECKING([for meteoio])
-	if test "x$METEOIO_ROOT" = "xno" ; then
+			AC_MSG_ERROR([Xlib (graphics library) provided (${GRAPHICS_LIB}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([done])
+	dnl }}}
+	dnl MeteoIO{{{
+	AC_ARG_WITH(
+		[meteoio-dir],
+		AS_HELP_STRING([--with-meteoio-dir=DIR], [use MeteoIO in conjunction with SNOWPACK model]),
+		[METEOIO_ROOT=${withval}],
+		[METEOIO_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for MeteoIO])
+	if test "x${METEOIO_ROOT}" == "xno"; then
 		HAVE_METEOIO=no
 	else
 		HAVE_METEOIO=yes
-		if ! test -d "$METEOIO_ROOT"; then
-			AC_MSG_ERROR([meteoio directory provided ($METEOIO_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_METEOIO)
-
-	dnl meteoio headers and libraries
-	if test "x$HAVE_METEOIO" == "xyes"; then
-		METEOIOINCL="-I$METEOIO_ROOT/include"
-		METEOIOLIB="-dy -L$METEOIO_ROOT/lib  -lmeteoio "
-
-		AC_DEFINE([_HAVE_METEOIO_],[1],[with meteoio])
+		if ! test -d "${METEOIO_ROOT}"; then
+			AC_MSG_ERROR([MeteoIO directory provided (${METEOIO_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_METEOIO}])
+
+	dnl MeteoIO libraries and header files
+	if test "x${HAVE_METEOIO}" == "xyes"; then
+		METEOIOINCL="-I${METEOIO_ROOT}/include"
+		METEOIOLIB="-dy -L${METEOIO_ROOT}/lib -lmeteoio"
+
+		AC_DEFINE([_HAVE_METEOIO_], [1], [with MeteoIO])
 		AC_SUBST([METEOIOINCL])
 		AC_SUBST([METEOIOLIB])
 	fi
-	AM_CONDITIONAL([METEOIO], [test x$HAVE_METEOIO = xyes])
-	dnl }}}
-	dnl snowpack{{{
-	AC_ARG_WITH([snowpack-dir],
-	  AS_HELP_STRING([--with-snowpack-dir=DIR], [use snowpack for surface mass balance model.]),
-	  [SNOWPACK_ROOT=$withval],[SNOWPACK_ROOT="no"])
-
-	dnl Check whether snowpack is enabled
-	AC_MSG_CHECKING([for snowpack])
-	if test "x$SNOWPACK_ROOT" = "xno" ; then
+	AM_CONDITIONAL([METEOIO], [test "x${HAVE_METEOIO}" == "xyes"])
+	dnl }}}
+	dnl SNOWPACK{{{
+	AC_ARG_WITH(
+		[snowpack-dir],
+		AS_HELP_STRING([--with-snowpack-dir=DIR], [use SNOWPACK for surface mass balance model]),
+		[SNOWPACK_ROOT=${withval}],
+		[SNOWPACK_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for SNOWPACK])
+	if test "x${SNOWPACK_ROOT}" == "xno"; then
 		HAVE_SNOWPACK=no
 	else
 		HAVE_SNOWPACK=yes
-		if ! test -d "$SNOWPACK_ROOT"; then
-			AC_MSG_ERROR([snowpack directory provided ($SNOWPACK_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_SNOWPACK)
-
-	dnl snowpack headers and libraries
-	if test "x$HAVE_SNOWPACK" == "xyes"; then
-		SNOWPACKINCL="-I$SNOWPACK_ROOT/include"
-		SNOWPACKLIB="-dy -L$SNOWPACK_ROOT/lib  -lsnowpack "
-
-		AC_DEFINE([_HAVE_SNOWPACK_],[1],[with snowpack for surface mass balance model])
+		if ! test -d "${SNOWPACK_ROOT}"; then
+			AC_MSG_ERROR([SNOWPACK directory provided (${SNOWPACK_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_SNOWPACK}])
+
+	dnl SNOWPACK libraries and header files
+	if test "x${HAVE_SNOWPACK}" == "xyes"; then
+		SNOWPACKINCL="-I${SNOWPACK_ROOT}/include"
+		SNOWPACKLIB="-dy -L${SNOWPACK_ROOT}/lib -lsnowpack"
+		AC_DEFINE([_HAVE_SNOWPACK_], [1], [with SNOWPACK for surface mass balance model])
 		AC_SUBST([SNOWPACKINCL])
 		AC_SUBST([SNOWPACKLIB])
 	fi
-	AM_CONDITIONAL([SNOWPACK], [test x$HAVE_SNOWPACK = xyes])
-	dnl }}}
-	dnl neopz{{{
-	AC_ARG_WITH([neopz-dir],
-		AS_HELP_STRING([--with-neopz-dir=DIR], [neopz root directory.]),
-		[NEOPZ_ROOT=$withval],[NEOPZ_ROOT="no"])
-
-	dnl Check whether neopz is enabled
-	AC_MSG_CHECKING([for neopz])
-	if test "x$NEOPZ_ROOT" = "xno" ; then
+	AM_CONDITIONAL([SNOWPACK], [test "x${HAVE_SNOWPACK}" == "xyes"])
+	dnl }}}
+	dnl NeoPZ{{{
+	AC_ARG_WITH(
+		[neopz-dir],
+		AS_HELP_STRING([--with-neopz-dir=DIR], [NeoPZ root directory]),
+		[NEOPZ_ROOT=${withval}],
+		[NEOPZ_ROOT="no"]
+	)
+	AC_MSG_CHECKING([for NeoPZ])
+	if test "x${NEOPZ_ROOT}" == "xno"; then
 		HAVE_NEOPZ=no
 	else
 		HAVE_NEOPZ=yes
-		if ! test -d "$NEOPZ_ROOT"; then
-			AC_MSG_ERROR([neopz directory provided ($NEOPZ_ROOT) does not exist]);
-		fi
-	fi
-	AC_MSG_RESULT($HAVE_NEOPZ)
-
-	dnl neopz headers and libraries
-	if test "x$HAVE_NEOPZ" == "xyes"; then
-	  NEOPZLIB="$NEOPZ_ROOT/lib/libpz.a"
-     NEOPZINCL=" -I$NEOPZ_ROOT/include"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Analysis"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Common"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/External"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Frontal"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Geom"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Integral"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/LinearSolvers"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Material"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Matrix"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Mesh"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Multigrid"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/PerfUtil"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Post"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Pre"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Refine"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Save"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Shape"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/SpecialMaps"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/StrMatrix"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/SubStruct"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Topology"
-	  NEOPZINCL+=" -I$NEOPZ_ROOT/include/Util"
-	  CXXFLAGS+=" -std=c++11"
-	  AC_DEFINE([_HAVE_NEOPZ_],[1],[with NEOPZ in ISSM src])
-	  AC_SUBST([NEOPZINCL])
-	  AC_SUBST([NEOPZLIB])
-	fi
-	AM_CONDITIONAL([NEOPZ], [test x$HAVE_NEOPZ = xyes])
-	dnl }}}
-
+		if ! test -d "${NEOPZ_ROOT}"; then
+			AC_MSG_ERROR([NeoPZ directory provided (${NEOPZ_ROOT}) does not exist!]);
+		fi
+	fi
+	AC_MSG_RESULT([${HAVE_NEOPZ}])
+
+	dnl NeoPZ libraries and header files
+	if test "x${HAVE_NEOPZ}" == "xyes"; then
+		NEOPZLIB="${NEOPZ_ROOT}/lib/libpz.a"
+		NEOPZINCL="-I${NEOPZ_ROOT}/include"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Analysis"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Common"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/External"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Frontal"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Geom"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Integral"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/LinearSolvers"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Material"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Matrix"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Mesh"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Multigrid"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/PerfUtil"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Post"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Pre"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Refine"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Save"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Shape"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/SpecialMaps"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/StrMatrix"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/SubStruct"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Topology"
+		NEOPZINCL+=" -I${NEOPZ_ROOT}/include/Util"
+		CXXFLAGS+=" -std=c++11"
+		AC_DEFINE([_HAVE_NEOPZ_], [1], [with NeoPZ in ISSM src])
+		AC_SUBST([NEOPZINCL])
+		AC_SUBST([NEOPZLIB])
+	fi
+	AM_CONDITIONAL([NEOPZ], [test "x${HAVE_NEOPZ}" == "xyes"])
+	dnl }}}
 	dnl Capabilities
 	dnl with-bamg{{{
-	AC_ARG_WITH([bamg],
-		AS_HELP_STRING([--with-bamg = YES],[compile with bamg capabilities (default is yes)]),
-		[BAMG=$withval],[BAMG=yes])
-	AC_MSG_CHECKING(for bamg capability compilation)
-
+	AC_ARG_WITH(
+		[bamg],
+		AS_HELP_STRING([--with-bamg=YES], [compile with BAMG capabilities (default: yes)]),
+		[BAMG=${withval}],
+		[BAMG=yes]
+	)
+	AC_MSG_CHECKING([for BAMG capability compilation])
 	HAVE_BAMG=no
-	if test "x$BAMG" = "xyes"; then
+	if test "x${BAMG}" == "xyes"; then
 		HAVE_BAMG=yes
-		AC_DEFINE([_HAVE_BAMG_],[1],[with bamg meshing capability])
-	fi
-	AM_CONDITIONAL([BAMG], [test x$HAVE_BAMG = xyes])
-	AC_MSG_RESULT($HAVE_BAMG)
+		AC_DEFINE([_HAVE_BAMG_], [1], [with BAMG meshing capability])
+	fi
+	AM_CONDITIONAL([BAMG], [test "x${HAVE_BAMG}" == "xyes"])
+	AC_MSG_RESULT([${HAVE_BAMG}])
 	dnl }}}
 	dnl with-ocean{{{
-	AC_ARG_WITH([ocean],
-		AS_HELP_STRING([--with-ocean = YES],[compile with ice/ocean coupling (default is no)]),
-		[OCEAN=$withval],[OCEAN=no])
-	AC_MSG_CHECKING(for ice/ocean capability compilation)
+	AC_ARG_WITH(
+		[ocean],
+		AS_HELP_STRING([--with-ocean = YES], [compile with ice/ocean coupling capability (default: no)]),
+		[OCEAN=${withval}],
+		[OCEAN=no]
+	)
+	AC_MSG_CHECKING(for ice/ocean coupling capability compilation)
 
 	HAVE_OCEAN=no
-	if test "x$OCEAN" = "xyes"; then
+	if test "x${OCEAN}" == "xyes"; then
 		HAVE_OCEAN=yes
-		AC_DEFINE([_HAVE_OCEAN_],[1],[with ice/ocean coupling capability])
-	fi
-	AM_CONDITIONAL([OCEAN], [test x$HAVE_OCEAN = xyes])
-	AC_MSG_RESULT($HAVE_OCEAN)
+		AC_DEFINE([_HAVE_OCEAN_], [1], [with ice/ocean coupling capability])
+	fi
+	AM_CONDITIONAL([OCEAN], [test "x${HAVE_OCEAN}" == "xyes"])
+	AC_MSG_RESULT([${HAVE_OCEAN}])
 	dnl }}}
 	dnl with-kml{{{
-	AC_ARG_WITH([kml],
-		AS_HELP_STRING([--with-kml = YES],[compile with kml capabilities (default is no)]),
-		[KML=$withval],[KML=no])
+	AC_ARG_WITH(
+		[kml],
+		AS_HELP_STRING([--with-kml=YES], [compile with kml capabilities (default: no)]),
+		[KML=${withval}],
+		[KML=no]
+	)
 	AC_MSG_CHECKING(for kml capability compilation)
 
 	HAVE_KML=no
-	if test "x$KML" = "xyes"; then
+	if test "x${KML}" == "xyes"; then
 		HAVE_KML=yes
-		AC_DEFINE([_HAVE_KML_],[1],[with kml capability])
-	fi
-	AM_CONDITIONAL([KML], [test x$HAVE_KML = xyes])
-	AC_MSG_RESULT($HAVE_KML)
+		AC_DEFINE([_HAVE_KML_], [1], [with kml capability])
+	fi
+	AM_CONDITIONAL([KML], [test "x${HAVE_KML}" == "xyes"])
+	AC_MSG_RESULT([${HAVE_KML}])
 	dnl }}}
 	dnl with-kriging{{{
-	AC_ARG_WITH([kriging],
-		AS_HELP_STRING([--with-kriging = YES],[compile with kriging capabilities (default is yes)]),
-		[KRIGING=$withval],[KRIGING=yes])
+	AC_ARG_WITH(
+		[kriging],
+		AS_HELP_STRING([--with-kriging=YES], [compile with kriging capabilities (default: yes)]),
+		[KRIGING=${withval}],
+		[KRIGING=yes]
+	)
 	AC_MSG_CHECKING(for kriging capability compilation)
 
 	HAVE_KRIGING=no
-	if test "x$KRIGING" = "xyes"; then
+	if test "x${KRIGING}" == "xyes"; then
 		HAVE_KRIGING=yes
-		AC_DEFINE([_HAVE_KRIGING_],[1],[with kriging capability])
-	fi
-	AM_CONDITIONAL([KRIGING], [test x$HAVE_KRIGING = xyes])
-	AC_MSG_RESULT($HAVE_KRIGING)
+		AC_DEFINE([_HAVE_KRIGING_], [1], [with kriging capability])
+	fi
+	AM_CONDITIONAL([KRIGING], [test "x${HAVE_KRIGING}" == "xyes"])
+	AC_MSG_RESULT([${HAVE_KRIGING}])
 	dnl }}}
 
@@ -2179,66 +2311,63 @@
 	dnl Platform specifics
 	dnl with-ios{{{
-	AC_ARG_WITH([ios],
-		AS_HELP_STRING([--with-ios = YES], [compile with iOS capabilities (default is no, alternatives are yes)]),
-		[IOS=$withval],[IOS=no])
+	AC_ARG_WITH(
+		[ios],
+		AS_HELP_STRING([--with-ios=YES], [compile with iOS capabilities (default: no)]),
+		[IOS=${withval}],
+		[IOS=no]
+	)
 	AC_MSG_CHECKING(for iOS compilation)
 
-	if test "x$IOS" = "xyes"; then
-		dnl defaults
+	HAVE_IOS=no
+	if test "x${IOS}" == "xyes"; then
 		HAVE_IOS=yes
-
-		AC_DEFINE([_HAVE_IOS_],[1],[with android capability])
-	elif test "x$IOS" = "xno"; then
-		HAVE_IOS=no
-	else
-	  AC_MSG_ERROR([--with-ios should be either no or yes])
-	fi
-	AM_CONDITIONAL([IOS], [test x$HAVE_IOS != xno])
-	AC_MSG_RESULT($HAVE_IOS)
+		AC_DEFINE([_HAVE_IOS_], [1], [with iOS capability])
+	fi
+	AM_CONDITIONAL([IOS], [test "x${HAVE_IOS}" != "xno"])
+	AC_MSG_RESULT([${HAVE_IOS}])
 	dnl }}}
 	dnl with-android{{{
-	AC_ARG_WITH([android],
-		AS_HELP_STRING([--with-android = EXE], [compile with android capabilities (default is no, alternatives are exe and jni)]),
-		[ANDROID=$withval],[ANDROID=no])
-	AC_MSG_CHECKING(for android capability compilation)
-
-	if test "x$ANDROID" = "xjni"; then
-
-		dnl defaults
+	AC_ARG_WITH(
+		[android],
+		AS_HELP_STRING([--with-android=EXE], [compile with Android capabilities (default: "no"; alternatives: "exe", "jni")]),
+		[ANDROID=${withval}],
+		[ANDROID=no])
+	AC_MSG_CHECKING([for Android capability compilation])
+
+	if test "x${ANDROID}" == "xjni"; then
 		HAVE_ANDROID=jni
-		AC_DEFINE([_HAVE_ANDROID_],[1],[with android capability])
-		AC_DEFINE([_HAVE_ANDROID_JNI_],[1],[with android jni])
-	elif test "x$ANDROID" = "xexe"; then
-		dnl defaults
+		AC_DEFINE([_HAVE_ANDROID_], [1], [with Android capability])
+		AC_DEFINE([_HAVE_ANDROID_JNI_], [1], [with Android Java Native Interface (JNI)])
+	elif test "x${ANDROID}" == "xexe"; then
 		HAVE_ANDROID=exe
-
-		AC_DEFINE([_HAVE_ANDROID_],[1],[with android capability])
-	elif test "x$ANDROID" = "xno"; then
+		AC_DEFINE([_HAVE_ANDROID_], [1], [with Android capability])
+	elif test "x${ANDROID}" == "xno"; then
 		HAVE_ANDROID=no
 	else
-	  AC_MSG_ERROR([--with-android should be either no, exe or jni])
-	fi
-	AM_CONDITIONAL([ANDROID], [test x$HAVE_ANDROID != xno])
-	AM_CONDITIONAL([ANDROIDJNI], [test x$HAVE_ANDROID = xjni])
-	AM_CONDITIONAL([ANDROIDEXE], [test x$HAVE_ANDROID = xexe])
-	AC_MSG_RESULT($HAVE_ANDROID)
+		AC_MSG_ERROR([--with-android should be either "no", "exe" or "jni"])
+	fi
+	AM_CONDITIONAL([ANDROID], [test "x${HAVE_ANDROID}" != "xno"])
+	AM_CONDITIONAL([ANDROIDJNI], [test "x${HAVE_ANDROID}" == "xjni"])
+	AM_CONDITIONAL([ANDROIDEXE], [test "x${HAVE_ANDROID}" == "xexe"])
+	AC_MSG_RESULT([${HAVE_ANDROID}])
 	dnl }}}
 	dnl with-android-ndk{{{
-	AC_ARG_WITH([android-ndk],
-	  AS_HELP_STRING([--with-android-ndk=DIR], [android-ndk root directory.]),
-	  [ANDROID_NDK_ROOT=$withval],[ANDROID_NDK_ROOT=""])
-	AC_MSG_CHECKING(with android ndk)
-
-	if test -d "$ANDROID_NDK_ROOT"; then
-		dnl defaults
+	AC_ARG_WITH(
+		[android-ndk],
+		AS_HELP_STRING([--with-android-ndk=DIR], [Android NDK root directory]),
+		[ANDROID_NDK_ROOT=${withval}],
+		[ANDROID_NDK_ROOT=""]
+	)
+	AC_MSG_CHECKING([with Android Native Development Kit (NDK)])
+
+	if test -d "${ANDROID_NDK_ROOT}"; then
 		HAVE_ANDROID_NDK=yes
-		ANDROID_NDKINCL="-I$ANDROID_NDK_ROOT/arm-linux-android-install/sysroot/usr/include"
-
-		AC_DEFINE([_HAVE_ANDROID_NDK_],[1],[with android ndk in ISSM src])
+		ANDROID_NDKINCL="-I${ANDROID_NDK_ROOT}/arm-linux-android-install/sysroot/usr/include"
+		AC_DEFINE([_HAVE_ANDROID_NDK_], [1], [with Android NDK in ISSM src])
 		AC_SUBST([ANDROID_NDKINCL])
 	else
 		HAVE_ANDROID_NDK=no
 	fi
-	AC_MSG_RESULT($HAVE_ANDROID_NDK)
+	AC_MSG_RESULT([${HAVE_ANDROID_NDK}])
 	dnl }}}
 
@@ -2246,115 +2375,121 @@
 	dnl optimization{{{
 	dnl -- bypass standard optimization -g -O2 -fPIC ?
-	AC_ARG_WITH([cxxoptflags],
-	  AS_HELP_STRING([--with-cxxoptflags = CXXOPTFLAGS], [optimization using CXX flags, ex: --with-cxxoptflags=-march=opteron -O3]),
-	  [CXXOPTFLAGS=$withval],[CXXOPTFLAGS="-g -O2 -fPIC"])
-	AC_MSG_CHECKING(for c++ optimization flags)
+	AC_ARG_WITH(
+		[cxxoptflags],
+		AS_HELP_STRING([--with-cxxoptflags=CXXOPTFLAGS], [C++ optimization flags (i.e. --with-cxxoptflags="-march=opteron -O3"]),
+		[CXXOPTFLAGS=${withval}],
+		[CXXOPTFLAGS="-g -O2 -fPIC"]
+	)
+	AC_MSG_CHECKING(for C++ optimization flags)
 	AC_SUBST([CXXOPTFLAGS])
-	AC_MSG_RESULT(done)
+	AC_MSG_RESULT([done])
 	dnl }}}
 	dnl multithreading{{{
-	AC_ARG_WITH([numthreads],
-	  AS_HELP_STRING([--with-numthreads = NUMTHREADS_VALUE],[numthreads, default is 1. ]),
-	  [NUMTHREADS_VALUE=$withval],[NUMTHREADS_VALUE=1])
+	AC_ARG_WITH(
+		[numthreads],
+		AS_HELP_STRING([--with-numthreads=NUMTHREADS_VALUE], [number of threads (default: 1)]),
+		[NUMTHREADS_VALUE=${withval}],
+		[NUMTHREADS_VALUE=1]
+	)
 	AC_MSG_CHECKING(for number of threads)
-	dnl defaults
+	dnl Check that supplied value is an integer
+	if [[ "${NUMTHREADS_VALUE}" != "${NUMTHREADS_VALUE}" 2> /dev/null ]]; then
+		AC_MSG_ERROR([Number of threads provided (${NUMTHREADS_VALUE}) is not an integer!]);
+	elif test "${NUMTHREADS_VALUE}" == "0"; then
+		AC_MSG_ERROR([Number of threads must be at least 1!]);
+	fi
 	MULTITHREADING=no
 	MULTITHREADINLIB=""
-	if test "$NUMTHREADS_VALUE" != "1"; then
-
+	if test "x${NUMTHREADS_VALUE}" != "x1"; then
 		MULTITHREADINGLIB="-lpthread -lrt"
 		case "${host_os}" in
-		*cygwin*)
-		MULTITHREADINGLIB="-lpthread -lrt"
-		;;
-		*linux*)
-		MULTITHREADINGLIB="-lpthread -lrt"
-		;;
-		*darwin*)
-		MULTITHREADINGLIB="-lpthread"
-		;;
+			*cygwin*)
+				MULTITHREADINGLIB="-lpthread -lrt"
+			;;
+			*linux*)
+				MULTITHREADINGLIB="-lpthread -lrt"
+			;;
+			*darwin*)
+				MULTITHREADINGLIB="-lpthread"
+			;;
 		esac
-		AC_DEFINE([_MULTITHREADING_],[1],[with numthreads enabled])
-	fi
-	dnl check that it is an integer
-	if [[ "$NUMTHREADS_VALUE" -eq   "$NUMTHREADS_VALUE" 2> /dev/null ]] ; then
-	 dnl cool we have an integer !
-	 :
-	else
-	 AC_MSG_ERROR([Number of threads provided ($NUMTHREADS_VALUE) is not an integer]);
-	fi
-	AC_DEFINE_UNQUOTED([_NUMTHREADS_],[$NUMTHREADS_VALUE],[number of threads])
+		AC_DEFINE([_MULTITHREADING_], [1], [with multithreading enabled])
+	fi
+	AC_DEFINE_UNQUOTED(_NUMTHREADS_, $NUMTHREADS_VALUE, [number of threads])
 	AC_SUBST([MULTITHREADINGLIB])
-	AC_MSG_RESULT($NUMTHREADS_VALUE)
-	dnl }}}
-	dnl 64bit {{{
-	AC_ARG_WITH([64bit-indices],
-	  AS_HELP_STRING([--with-64bit-indices = bool], [use 64 bit integers, default 0, ex: --with-64bit-indices=1]),
-	  [USE_64BIT_INDICES=$withval],[USE_64BIT_INDICES=0])
-	AC_MSG_CHECKING(for 64 bit indices)
-
-	if test "$USE_64BIT_INDICES" == "1"; then
-	AC_DEFINE([ISSM_USE_64BIT_INDICES],[1],[with 64 bits indices])
-	else
-	AC_DEFINE([ISSM_USE_64BIT_INDICES],[0],[with 64 bits indices])
-	fi
-	AC_MSG_RESULT($USE_64BIT_INDICES)
-	dnl }}}
-
-	dnl Checks
-	dnl checks{{{
-		AC_MSG_CHECKING(consistency between all libraries)
-
-		  dnl check that if petsc is requested , mpi should be specified
-		  if test "$HAVE_PETSC" = "yes" ; then
-				if test "$HAVE_MPI" = "NO";  then
-					 AC_MSG_ERROR([petsc requires mpi!]);
-				fi
-		  fi
-
-		  dnl check that we have either python or matlab support if we compile the modules
-		  if test "$MODULES_VALUE" = "yes"  && test "$HAVE_MATLAB" = "no" && test "$HAVE_PYTHON" = "no"; then
-				AC_MSG_ERROR([need at least python or matlab support to compile modules (or use --with-modules=no)]);
-		  fi
-
-       dnl check that fortran is provided if GiaIvins is on
-		 if test "$HAVE_GIAIVINS" = "yes" &&  test "$HAVE_FORTRAN" = "no" ; then
-			  AC_MSG_ERROR([need fortran compiler to compile GiaIvins (or use --without-GiaIvins )]);
-		 fi
-
-       dnl check that fortran is provided if Love is on
-		 if test "$HAVE_LOVE" = "yes" &&  test "$HAVE_FORTRAN" = "no" ; then
-			  AC_MSG_ERROR([need fortran compiler to compile Love (or use --without-Love)]);
-		 fi
-
-		  dnl check that if we have MPI, we have metis
-		  if test "$HAVE_METIS" = "yes"  && test "$HAVE_MPI" = "no" ; then
-				AC_MSG_ERROR([need mpi if using the metis partitioner!]);
-		  fi
-
-		dnl check that if we run adolc, we don't compile krigging.exe
-		if test "$HAVE_ADOLC" = "yes"  && test "$HAVE_KRIGING" = "yes" ; then
-			AC_MSG_ERROR([cannot compile kriging.exe under adolc conditions!]);
-		fi
-		dnl check that if we run adolc, we don't use PETSc for now
-		if test "$HAVE_ADOLC" = "yes"  && test "$HAVE_PETSC" = "yes" ; then
-			AC_MSG_ERROR([cannot compile ISSM with both PETSc and adolc]);
-		fi
-		if test "$HAVE_ADOLC" = "yes"  && test "$HAVE_CODIPACK" = "yes" ; then
-			AC_MSG_ERROR([cannot compile ISSM with both ADOLC and CoDiPack]);
-		fi
-		if test "$HAVE_ADJOINTMPI" = "yes"  && test "$HAVE_MEDIPACK" = "yes" ; then
-			AC_MSG_ERROR([cannot compile ISSM with both MeDiPack and AdjointMPI]);
-		fi
-		dnl check that if we run meteoio, we have snowpack also
-		if test "$HAVE_METEOIO" = "yes"  && test "$HAVE_SNOWPACK" = "no" ; then
-			AC_MSG_ERROR([cannot compile MeteoIO package without Snowpack!]);
-		fi
-		dnl check that if we run snowpack, we have meteoio also
-		if test "$HAVE_METEOIO" = "no"  && test "$HAVE_SNOWPACK" = "yes" ; then
-			AC_MSG_ERROR([cannot compile Snowpack package without MeteoIO!]);
-		fi
-
-		AC_MSG_RESULT(done)
-		dnl }}}
+	AC_MSG_RESULT([${NUMTHREADS_VALUE}])
+	dnl }}}
+	dnl 64-bit indices{{{
+	AC_ARG_WITH(
+		[64bit-indices],
+		AS_HELP_STRING([--with-64bit-indices=bool], [use 64-bit indices (default: 0)]),
+		[USE_64BIT_INDICES=${withval}],
+		[USE_64BIT_INDICES=0]
+	)
+	AC_MSG_CHECKING([for 64-bit indices])
+
+	if test "x${USE_64BIT_INDICES}" == "x1"; then
+		AC_DEFINE([ISSM_USE_64BIT_INDICES], [1], [with 64-bit indices])
+	else
+		AC_DEFINE([ISSM_USE_64BIT_INDICES], [0], [with 64-bit indices])
+	fi
+	AC_MSG_RESULT([${USE_64BIT_INDICES}])
+	dnl }}}
+
+	dnl Checks {{{
+	AC_MSG_CHECKING(consistency between all libraries)
+
+	dnl Check that if PETSc is requested, MPI is specified
+	if test "x${HAVE_PETSC}" == "xyes"; then
+		if test "x${HAVE_MPI}" == "xno"; then
+			AC_MSG_ERROR([PETSc requires MPI!]);
+		fi
+	fi
+
+	dnl Check that we have MATLAB and/or Python support if we compile the modules
+	if test "x${MODULES_VALUE}" == "xyes" && test "${HAVE_MATLAB}" == "xno" && test "${HAVE_PYTHON}" == "xno"; then
+		AC_MSG_ERROR([need at least MATLAB and/or Python support to compile modules! (or use --with-modules=no)]);
+	fi
+
+	dnl Check that Fortran is provided if GiaIvins is on
+	if test "x${HAVE_GIAIVINS}" == "xyes" &&  test "${HAVE_FORTRAN}" == "xno"; then
+		AC_MSG_ERROR([need Fortran compiler to compile GiaIvins! (or use --without-GiaIvins )]);
+	fi
+
+	dnl Check that Fortran is provided if Love is on
+	if test "x${HAVE_LOVE}" == "xyes" && test "x${HAVE_FORTRAN}" == "xno"; then
+		AC_MSG_ERROR([need Fortran compiler to compile Love! (or use --without-Love)]);
+	fi
+
+	dnl Check that if we have MPI, we have METIS
+	if test "x${HAVE_METIS}" == "xyes" && test "x${HAVE_MPI}" == "xno"; then
+		AC_MSG_ERROR([need MPI if using the METIS partitioner!]);
+	fi
+
+	dnl Check that if we run ADOL-C, we don't compile kriging.exe
+	if test "x$HAVE_ADOLC" == "xyes" && test "${HAVE_KRIGING}" == "xyes"; then
+		AC_MSG_ERROR([cannot compile kriging.exe under ADOL-C conditions!]);
+	fi
+
+	dnl Check that if we run ADOL-C, we don't use PETSc for now
+	if test "x${HAVE_ADOLC}" == "xyes" && test "x${HAVE_PETSC}" == "xyes"; then
+		AC_MSG_ERROR([cannot compile ISSM with both PETSc and ADOL-C!]);
+	fi
+	if test "x${HAVE_ADOLC}" == "xyes" && test "x${HAVE_CODIPACK}" == "xyes"; then
+		AC_MSG_ERROR([cannot compile ISSM with both ADOL-C and CoDiPack!]);
+	fi
+	if test "x${HAVE_ADJOINTMPI}" == "xyes" && test "x${HAVE_MEDIPACK}" == "xyes"; then
+		AC_MSG_ERROR([cannot compile ISSM with both MeDiPack and AdjointMPI!]);
+	fi
+	dnl Check that if we run MeteoIO, we have SNOWPACK also
+	if test "x${HAVE_METEOIO}" == "xyes" && test "x${HAVE_SNOWPACK}" == "xno"; then
+		AC_MSG_ERROR([cannot compile MeteoIO package without SNOWPACK!]);
+	fi
+	dnl Check that if we run SNOWPACK, we have MeteoIO also
+	if test "${HAVE_METEOIO}" == "xno" && test "${HAVE_SNOWPACK}" == "xyes"; then
+		AC_MSG_ERROR([cannot compile SNOWPACK package without MeteoIO!]);
+	fi
+
+	AC_MSG_RESULT([done])
+	dnl }}}
 ])
Index: /issm/trunk-jpl/packagers/linux/package-issm-linux-binaries-with_dakota.sh
===================================================================
--- /issm/trunk-jpl/packagers/linux/package-issm-linux-binaries-with_dakota.sh	(revision 24593)
+++ /issm/trunk-jpl/packagers/linux/package-issm-linux-binaries-with_dakota.sh	(revision 24593)
@@ -0,0 +1,157 @@
+#!/bin/bash
+
+
+## Constants
+#
+LIBGFORTRAN="/usr/lib/x86_64-linux-gnu/libgfortran.so.5.0.0" # Important that this is the library itself
+LIBGFORTRAN_DIST="${ISSM_DIR}/lib/libgfortran.so.5" # Important the file name matches the SONAME entry in the binaries and other shared libraries which link to it
+MATLAB_NROPTIONS="'id',[IdFromString('Dakota')],'exclude',[234,244,250,417,444,445]"
+MATLAB_PATH="/usr/local/MATLAB/R2019b" # Exclude any tests with transient solutions that require a restart
+PACKAGE="ISSM" # Name of directory to copy distributable files to
+
+# Exclude any tests with transient solutions that require a restart
+#
+# NOTE:
+# - All non-excluded tests were running until recent changes to QMU
+# - 418 fails with "malloc(): invalid next size (unsorted)""
+#
+PYTHON_NROPTIONS="--include_name 'Dakota' --exclude 234 244 250 417 418 444 445"
+TARBALL_NAME="issm-linux-with_dakota"
+TARBALL="${TARBALL_NAME}.tar.gz"
+
+# Clean up from previous packaging
+echo "Cleaning up existing assets"
+cd ${ISSM_DIR}
+rm -rf ${PACKAGE}
+mkdir ${PACKAGE}
+
+# Add/modify required binaries
+cd ${ISSM_DIR}/bin
+
+echo "Modifying generic"
+cat generic_static.m | sed -e "s/generic_static/generic/g" > generic.m
+cat generic_static.py | sed -e "s/generic_static/generic/g" > generic.py
+
+echo "Moving MPICH binaries to bin/"
+if [ -f ${ISSM_DIR}/externalpackages/mpich/install/bin/mpiexec ]; then
+	cp ${ISSM_DIR}/externalpackages/mpich/install/bin/mpiexec .
+	cp ${ISSM_DIR}/externalpackages/mpich/install/bin/hydra_pmi_proxy .
+else
+	echo "MPICH not found"
+fi
+
+# Add/modify required libraries
+echo "Moving libgfortran to lib/"
+cp ${LIBGFORTRAN} ${LIBGFORTRAN_DIST}
+
+# Run tests
+echo "Running tests"
+cd ${ISSM_DIR}/test/NightlyRun
+
+# Check that MATLAB tests run
+echo "Running MATLAB tests"
+
+rm matlab.log 2> /dev/null
+
+# Run MATLAB tests redirecting output to logfile and suppressing output to console
+${MATLAB_PATH}/bin/matlab -nojvm -nosplash -r "try, addpath ${ISSM_DIR}/bin ${ISSM_DIR}/lib; runme(${MATLAB_NROPTIONS}); exit; catch me,fprintf('%s',getReport(me)); exit; end" -logfile matlab.log &> /dev/null
+
+# Check that MATLAB did not exit in error
+matlabExitCode=`echo $?`
+matlabExitedInError=`grep -E "Activation cannot proceed|license|Error" matlab.log | wc -l`
+
+if [[ ${matlabExitCode} -ne 0 || ${matlabExitedInError} -ne 0 ]]; then
+	echo "----------MATLAB exited in error!----------"
+	cat matlab.log
+	echo "-----------End of matlab.log-----------"
+
+	# Clean up execution directory
+	rm -rf ${ISSM_DIR}/execution/*
+
+	exit 1
+fi
+
+# Check that all MATLAB tests passed
+numMatlabTestsFailed=`cat matlab.log | grep -c -e "FAILED|ERROR"`
+
+if [[ ${numMatlabTestsFailed} -ne 0 ]]; then
+	echo "One or more MATLAB tests FAILED"
+	exit 1;
+else
+	echo "All MATLAB tests PASSED"
+fi
+
+# Check that Python tests run
+echo "Running Python tests"
+
+export PATH="${PATH}:${ISSM_DIR}/bin"
+export PYTHONPATH="${ISSM_DIR}/src/m/dev"
+export PYTHONSTARTUP="${PYTHONPATH}/devpath.py"
+export PYTHONUNBUFFERED=1 # We don't want Python to buffer output, otherwise issm.exe output is not captured
+
+rm python.log 2> /dev/null
+./runme.py ${PYTHON_NROPTIONS} &> python.log 2>&1
+
+# Check that Python did not exit in error
+pythonExitCode=`echo $?`
+pythonExitedInError=`grep -E "runme.py: error" python.log | wc -l`
+
+if [[ ${pythonExitCode} -ne 0 || ${pythonExitedInError} -ne 0 ]]; then
+	echo "----------Python exited in error!----------"
+	cat python.log
+	echo "-----------End of python.log-----------"
+
+	# Clean up execution directory
+	rm -rf ${ISSM_DIR}/execution/*
+
+	exit 1
+fi
+
+# Check that all Python tests passed
+numPythonTestsFailed=`cat python.log | grep -c -e "FAILED|ERROR"`
+
+if [[ ${numPythonTestsFailed} -ne 0 ]]; then
+	echo "One or more Python tests FAILED"
+	exit 1;
+else
+	echo "All Python tests PASSED"
+fi
+
+# Create tarball
+cd ${ISSM_DIR}
+rm -f ${TARBALL}
+svn cleanup --remove-ignored --remove-unversioned test # Clean up test directory (before copying to package)
+echo "Copying assets to package: ${PACKAGE}"
+cp -rf bin examples lib scripts test ${PACKAGE}/
+echo "Cleaning up unneeded/unwanted files"
+python -m compileall ${PACKAGE}/bin # Precompile all Python scripts to bytecode
+rm -f ${PACKAGE}/bin/*.py # Remove all Python scripts
+rm -f ${PACKAGE}/lib/*.a # Remove static libraries from package
+rm -f ${PACKAGE}/lib/*.la # Remove libtool libraries from package
+echo "Creating tarball: ${TARBALL_NAME}"
+tar -czf ${TARBALL} ${PACKAGE}
+ls -lah ${ISSM_DIR}/${TARBALL}
+
+echo "Shipping binaries to website"
+
+# We're using public key authentication method to upload the tarball The
+# following lines check to see if the SSH Agent is running. If not, then it is
+# started and relevant information is forwarded to a script.
+pgrep "ssh-agent" > /dev/null
+if [ $? -ne 0 ]; then
+	echo "SSH Agent is not running. Starting it..."
+	ssh-agent > ~/.ssh/agent.sh
+else
+	echo "SSH Agent is running..."
+fi
+
+source ~/.ssh/agent.sh
+ssh-add ~/.ssh/debian_linux-vm-to-ross
+
+scp ${TARBALL} ross.ics.uci.edu:/var/www/html/${TARBALL}
+
+if [ $? -ne 0 ]; then
+	echo "The upload failed."
+	echo "Perhaps the SSH Agent was started by some other means."
+	echo "Try killing the agent and running again."
+fi
Index: /issm/trunk-jpl/packagers/linux/package-issm-linux-binaries.sh
===================================================================
--- /issm/trunk-jpl/packagers/linux/package-issm-linux-binaries.sh	(revision 24593)
+++ /issm/trunk-jpl/packagers/linux/package-issm-linux-binaries.sh	(revision 24593)
@@ -0,0 +1,110 @@
+#!/bin/bash
+
+
+## Constants
+#
+LIBGFORTRAN="/usr/lib/x86_64-linux-gnu/libgfortran.so.5.0.0" # Important that this is the library itself
+LIBGFORTRAN_DIST="${ISSM_DIR}/lib/libgfortran.so.5" # Important the file name matches the SONAME entry in the binaries and other shared libraries which link to it
+MATLAB_NROPTIONS="'exclude',[IdFromString('Dakota'),125,126]" # Exclude Dakota tests and any tests with transient solutions that require a restart
+MATLAB_PATH="/usr/local/MATLAB/R2019b"
+PACKAGE="ISSM" # Name of directory to copy distributable files to
+TARBALL_NAME="issm-linux"
+TARBALL="${TARBALL_NAME}.tar.gz"
+
+# Clean up from previous packaging
+echo "Cleaning up existing assets"
+cd ${ISSM_DIR}
+rm -rf ${PACKAGE}
+mkdir ${PACKAGE}
+
+# Add/modify required binaries and libraries
+cd ${ISSM_DIR}/bin
+
+echo "Modify generic"
+cat generic_static.m | sed -e "s/generic_static/generic/g" > generic.m
+rm generic_static.m
+
+echo "Moving MPICH binaries to bin/"
+if [ -f ${ISSM_DIR}/externalpackages/mpich/install/bin/mpiexec ]; then
+	cp ${ISSM_DIR}/externalpackages/mpich/install/bin/mpiexec .
+	cp ${ISSM_DIR}/externalpackages/mpich/install/bin/hydra_pmi_proxy
+else
+	echo "MPICH not found"
+fi
+
+echo "Moving libgfortran to lib/"
+cp ${LIBGFORTRAN} ${LIBGFORTRAN_DIST}
+
+# Run tests
+echo "Running tests"
+cd ${ISSM_DIR}/test/NightlyRun
+
+# Check that MATLAB tests run
+echo "Running MATLAB tests"
+
+rm matlab.log 2> /dev/null
+
+# Run MATLAB tests redirecting output to logfile and suppressing output to console
+${MATLAB_PATH}/bin/matlab -nojvm -nosplash -r "try, addpath ${ISSM_DIR}/bin ${ISSM_DIR}/lib; runme(${MATLAB_NROPTIONS}); exit; catch me,fprintf('%s',getReport(me)); exit; end" -logfile matlab.log &> /dev/null
+
+# Check that MATLAB did not exit in error
+matlabExitCode=`echo $?`
+matlabExitedInError=`grep -E "Activation cannot proceed|license|Error" matlab.log | wc -l`
+
+if [[ ${matlabExitCode} -ne 0 || ${matlabExitedInError} -ne 0 ]]; then
+	echo "----------MATLAB exited in error!----------"
+	cat matlab.log
+	echo "-----------End of matlab.log-----------"
+
+	# Clean up execution directory
+	rm -rf ${ISSM_DIR}/execution/*
+
+	exit 1
+fi
+
+# Check that all MATLAB tests passed
+numMatlabTestsFailed=`cat matlab.log | grep -c -e "FAILED|ERROR"`
+
+if [[ ${numMatlabTestsFailed} -ne 0 ]]; then
+	echo "One or more MATLAB tests FAILED"
+	exit 1;
+else
+	echo "All MATLAB tests PASSED"
+fi
+
+# Create tarball
+cd ${ISSM_DIR}
+rm -f ${TARBALL}
+svn cleanup --remove-ignored --remove-unversioned test # Clean up test directory (before copying to package)
+echo "Copying assets to package: ${PACKAGE}"
+cp -rf bin examples lib scripts test ${PACKAGE}/
+echo "Cleaning up unneeded/unwanted files"
+rm -f ${PACKAGE}/lib/*.a # Remove static libraries from package
+rm -f ${PACKAGE}/lib/*.la # Remove libtool libraries from package
+echo "Creating tarball: ${TARBALL_NAME}"
+tar -czf ${TARBALL} ${PACKAGE}
+ls -lah ${ISSM_DIR}/${TARBALL}
+
+echo "Shipping binaries to website"
+
+# We're using public key authentication method to upload the tarball The
+# following lines check to see if the SSH Agent is running. If not, then it is
+# started and relevant information is forwarded to a script.
+pgrep "ssh-agent" > /dev/null
+if [ $? -ne 0 ]; then
+	echo "SSH Agent is not running. Starting it..."
+	ssh-agent > ~/.ssh/agent.sh
+else
+	echo "SSH Agent is running..."
+fi
+
+source ~/.ssh/agent.sh
+ssh-add ~/.ssh/debian_linux-vm-to-ross
+
+scp ${TARBALL} ross.ics.uci.edu:/var/www/html/${TARBALL}
+
+if [ $? -ne 0 ]; then
+	echo "The upload failed."
+	echo "Perhaps the SSH Agent was started by some other means."
+	echo "Try killing the agent and running again."
+fi
Index: /issm/trunk-jpl/scripts/devpath.py
===================================================================
--- /issm/trunk-jpl/scripts/devpath.py	(revision 24593)
+++ /issm/trunk-jpl/scripts/devpath.py	(revision 24593)
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+# NOTE: This script is a stripped-down version of
+#       $ISSM_DIR/src/m/dev/devpath.py and is intended only for loading ISSM in
+#       order to test our distributable packages. It assumes the following is
+#       set before $ISSM_DIR/test/NightlyRun/runme.py is called,
+#
+#           export ISSM_DIR=</path/to/ISSM>
+#			export PATH="${PATH}:${ISSM_DIR}/bin"
+#           export PYTHONPATH="${ISSM_DIR}/scripts"
+#           export PYTHONSTARTUP="${PYTHONPATH}/devpath.py"
+#           export PYTHONUNBUFFERED=1
+#
+
+import os
+import sys
+
+ISSM_DIR = os.getenv('ISSM_DIR')
+sys.path.append(ISSM_DIR + '/bin')
+sys.path.append(ISSM_DIR + '/lib')
+
+from issmversion import issmversion
Index: /issm/trunk-jpl/scripts/test-issm-linux-binaries-with_dakota.sh
===================================================================
--- /issm/trunk-jpl/scripts/test-issm-linux-binaries-with_dakota.sh	(revision 24593)
+++ /issm/trunk-jpl/scripts/test-issm-linux-binaries-with_dakota.sh	(revision 24593)
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+# This script is intended to test binaries downloaded to a user-end machine.
+#
+# NOTE: Tarball must already exist in INSTALL_DIR
+#
+
+MATLAB_NROPTIONS="'id',[IdFromString('Dakota')],'exclude',[234,244,250,417,444,445]"  # Exclude any tests with transient solutions that require a restart
+MATLAB_PATH="/usr/local/MATLAB/R2019b"
+INSTALL_DIR=~/Downloads
+PACKAGE_NAME="ISSM"
+
+# Exclude any tests with transient solutions that require a restart
+#
+# NOTE:
+# - All non-excluded tests were running until recent changes to QMU
+# - 418 fails with "malloc(): invalid next size (unsorted)""
+#
+PYTHON_NROPTIONS="--include_name 'Dakota' --exclude 234 244 250 417 418 444 445"
+TARBALL_NAME="issm-linux-with_dakota"
+TARBALL="${TARBALL_NAME}.tar.gz"
+
+cd ${INSTALL_DIR}
+rm -rf ${PACKAGE_NAME}
+tar -zxvf ${TARBALL}
+cd ${PACKAGE_NAME}/test/NightlyRun
+
+# Check that MATLAB tests run
+echo "Running MATLAB tests"
+rm matlab.log 2> /dev/null
+
+# Run MATLAB tests redirecting output to logfile and suppressing output to console
+${MATLAB_PATH}/bin/matlab -nojvm -nosplash -r "try, addpath ../../bin; addpath ../../lib; runme(${MATLAB_NROPTIONS}); exit; catch me,fprintf('%s',getReport(me)); exit; end" -logfile matlab.log &> /dev/null
+
+# Check that MATLAB did not exit in error
+matlabExitCode=`echo $?`
+matlabExitedInError=`grep -E "Activation cannot proceed|license|Error" matlab.log | wc -l`
+
+if [[ ${matlabExitCode} -ne 0 || ${matlabExitedInError} -ne 0 ]]; then
+	echo "----------MATLAB exited in error!----------"
+	cat matlab.log
+	echo "-----------End of matlab.log-----------"
+
+	# Clean up execution directory
+	rm -rf ${ISSM_DIR}/execution/*
+
+	exit 1
+fi
+
+# Check that all MATLAB tests passed
+numMatlabTestsFailed=`cat matlab.log | grep -c -e "FAILED|ERROR"`
+
+if [[ ${numMatlabTestsFailed} -ne 0 ]]; then
+	echo "One or more MATLAB tests FAILED"
+	exit 1;
+else
+	echo "All MATLAB tests PASSED"
+fi
+
+# Check that Python tests run
+echo "Running Python tests"
+
+export ISSM_DIR="${INSTALL_DIR}"
+export PATH="${PATH}:${ISSM_DIR}/bin"
+export PYTHONPATH="${ISSM_DIR}/scripts"
+export PYTHONSTARTUP="${PYTHONPATH}/devpath.py"
+export PYTHONUNBUFFERED=1 # We don't want Python to buffer output, otherwise issm.exe output is not captured
+
+rm python.log 2> /dev/null
+./runme.py ${PYTHON_NROPTIONS} &> python.log 2>&1
+
+# Check that Python did not exit in error
+pythonExitCode=`echo $?`
+pythonExitedInError=`grep -E "runme.py: error" python.log | wc -l`
+
+if [[ ${pythonExitCode} -ne 0 || ${pythonExitedInError} -ne 0 ]]; then
+	echo "----------Python exited in error!----------"
+	cat python.log
+	echo "-----------End of python.log-----------"
+
+	# Clean up execution directory
+	rm -rf ${ISSM_DIR}/execution/*
+
+	exit 1
+fi
+
+# Check that all Python tests passed
+numPythonTestsFailed=`cat python.log | grep -c -e "FAILED|ERROR"`
+
+if [[ ${numPythonTestsFailed} -ne 0 ]]; then
+	echo "One or more Python tests FAILED"
+	exit 1;
+else
+	echo "All Python tests PASSED"
+fi
Index: /issm/trunk-jpl/scripts/test-issm-linux-binaries.sh
===================================================================
--- /issm/trunk-jpl/scripts/test-issm-linux-binaries.sh	(revision 24593)
+++ /issm/trunk-jpl/scripts/test-issm-linux-binaries.sh	(revision 24593)
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+# This script is intended to test binaries downloaded to a user-end machine.
+#
+# NOTE: Tarball must already exist in INSTALL_DIR
+#
+
+MATLAB_NROPTIONS="'exclude',[IdFromString('Dakota'),125,126]" # Exclude Dakota tests and any tests with transient solutions that require a restart
+MATLAB_PATH="/usr/local/MATLAB/R2019b"
+INSTALL_DIR=~/Downloads
+PACKAGE_NAME="ISSM"
+TARBALL_NAME="issm-linux"
+TARBALL="${TARBALL_NAME}.tar.gz"
+
+cd ${INSTALL_DIR}
+rm -rf ${PACKAGE_NAME}
+tar -zxvf ${TARBALL}
+cd ${PACKAGE_NAME}/test/NightlyRun
+
+# Check that MATLAB tests run
+echo "Running MATLAB tests"
+rm matlab.log 2> /dev/null
+
+# Run MATLAB tests redirecting output to logfile and suppressing output to console
+${MATLAB_PATH}/bin/matlab -nojvm -nosplash -r "try, addpath ../../bin; addpath ../../lib; runme(${MATLAB_NROPTIONS}); exit; catch me,fprintf('%s',getReport(me)); exit; end" -logfile matlab.log &> /dev/null
+
+# Check that MATLAB did not exit in error
+matlabExitCode=`echo $?`
+matlabExitedInError=`grep -E "Activation cannot proceed|license|Error" matlab.log | wc -l`
+
+if [[ ${matlabExitCode} -ne 0 || ${matlabExitedInError} -ne 0 ]]; then
+	echo "----------MATLAB exited in error!----------"
+	cat matlab.log
+	echo "-----------End of matlab.log-----------"
+
+	# Clean up execution directory
+	rm -rf ${ISSM_DIR}/execution/*
+
+	exit 1
+fi
+
+# Check that all MATLAB tests passed
+numMatlabTestsFailed=`cat matlab.log | grep -c -e "FAILED|ERROR"`
+
+if [[ ${numMatlabTestsFailed} -ne 0 ]]; then
+	echo "One or more MATLAB tests FAILED"
+	exit 1;
+else
+	echo "All MATLAB tests PASSED"
+fi
Index: /issm/trunk-jpl/src/c/Makefile.am
===================================================================
--- /issm/trunk-jpl/src/c/Makefile.am	(revision 24592)
+++ /issm/trunk-jpl/src/c/Makefile.am	(revision 24593)
@@ -8,10 +8,10 @@
 #Library declaration {{{
 if !WINDOWS
-lib_LTLIBRARIES = libISSMCore.la libISSMOverload.la 
+lib_LTLIBRARIES = libISSMCore.la libISSMOverload.la
 if WRAPPERS
 lib_LTLIBRARIES += libISSMModules.la
 endif
 else
-noinst_LTLIBRARIES = libISSMCore.la libISSMOverload.la 
+noinst_LTLIBRARIES = libISSMCore.la libISSMOverload.la
 if WRAPPERS
 noinst_LTLIBRARIES += libISSMModules.la
@@ -22,41 +22,43 @@
 #Core sources
 #BAMG sources  {{{
-issm_sources = 
+issm_sources =
 if BAMG
-issm_sources += ./bamg/BamgGeom.cpp\
-					 ./bamg/BamgMesh.cpp\
-					 ./bamg/BamgOpts.cpp\
-					 ./bamg/CrackedEdge.cpp\
-					 ./bamg/Curve.cpp\
-					 ./bamg/Edge.cpp\
-					 ./bamg/GeomEdge.cpp\
-					 ./bamg/GeomSubDomain.cpp\
-					 ./bamg/GeomVertex.cpp\
-					 ./bamg/Geometry.cpp\
-					 ./bamg/ListofIntersectionTriangles.cpp\
-					 ./bamg/EigenMetric.cpp\
-					 ./bamg/Metric.cpp\
-					 ./bamg/BamgQuadtree.cpp\
-					 ./bamg/SetOfE4.cpp\
-					 ./bamg/SubDomain.cpp\
-					 ./bamg/AdjacentTriangle.cpp\
-					 ./bamg/Triangle.cpp\
-					 ./bamg/BamgVertex.cpp\
-					 ./bamg/VertexOnEdge.cpp\
-					 ./bamg/VertexOnGeom.cpp\
-					 ./bamg/VertexOnVertex.cpp\
-					 ./bamg/Mesh.cpp\
-					 ./shared/Bamg/BigPrimeNumber.cpp\
-					 ./modules/Bamgx/Bamgx.cpp\
-					 ./modules/BamgConvertMeshx/BamgConvertMeshx.cpp\
-					 ./modules/BamgTriangulatex/BamgTriangulatex.cpp
+issm_sources += \
+	./bamg/BamgGeom.cpp \
+	./bamg/BamgMesh.cpp \
+	./bamg/BamgOpts.cpp \
+	./bamg/CrackedEdge.cpp \
+	./bamg/Curve.cpp \
+	./bamg/Edge.cpp \
+	./bamg/GeomEdge.cpp \
+	./bamg/GeomSubDomain.cpp \
+	./bamg/GeomVertex.cpp \
+	./bamg/Geometry.cpp \
+	./bamg/ListofIntersectionTriangles.cpp \
+	./bamg/EigenMetric.cpp \
+	./bamg/Metric.cpp \
+	./bamg/BamgQuadtree.cpp \
+	./bamg/SetOfE4.cpp \
+	./bamg/SubDomain.cpp \
+	./bamg/AdjacentTriangle.cpp \
+	./bamg/Triangle.cpp \
+	./bamg/BamgVertex.cpp \
+	./bamg/VertexOnEdge.cpp \
+	./bamg/VertexOnGeom.cpp \
+	./bamg/VertexOnVertex.cpp \
+	./bamg/Mesh.cpp \
+	./shared/Bamg/BigPrimeNumber.cpp \
+	./modules/Bamgx/Bamgx.cpp \
+	./modules/BamgConvertMeshx/BamgConvertMeshx.cpp \
+	./modules/BamgTriangulatex/BamgTriangulatex.cpp
 
 #do not include AmrBamg with AD
 if ADOLC
-issm_sources +=./shared/Numerics/isnan.cpp \
-					./shared/MemOps/MemOps.cpp
+issm_sources += \
+	./shared/Numerics/isnan.cpp \
+	./shared/MemOps/MemOps.cpp
 else
 if CODIPACK
-issm_sources +=./shared/Numerics/isnan.cpp
+issm_sources += ./shared/Numerics/isnan.cpp
 else
 issm_sources += ./classes/AmrBamg.cpp
@@ -66,264 +68,265 @@
 #}}}
 #Core sources{{{
-issm_sources += ./datastructures/DataSet.cpp\
-					./classes/gauss/GaussSeg.cpp\
-					./classes/gauss/GaussTria.cpp\
-					./classes/gauss/GaussTetra.cpp\
-					./classes/gauss/GaussPenta.cpp\
-					./classes/IoModel.cpp\
-					./classes/FemModel.cpp\
-					./classes/Loads/Friction.cpp\
-					./classes/Constraints/SpcTransient.cpp\
-					./classes/DependentObject.cpp\
-					./classes/Contours.cpp\
-					./classes/Vertices.cpp\
-					./classes/Nodes.cpp\
-					./classes/Numberedcostfunction.cpp\
-					./classes/Misfit.cpp\
-					./classes/Cfsurfacesquare.cpp\
-					./classes/Cfdragcoeffabsgrad.cpp\
-					./classes/Cfsurfacelogvel.cpp\
-					./classes/Regionaloutput.cpp\
-					./classes/Nodalvalue.cpp\
-					./classes/Node.cpp\
-					./classes/Vertex.cpp\
-					./classes/Hook.cpp\
-					./classes/Radar.cpp\
-					./classes/ExternalResults/Results.cpp\
-					./classes/Elements/Element.cpp\
-					./classes/Elements/Elements.cpp\
-					./classes/Elements/ElementHook.cpp\
-					./classes/Elements/Seg.cpp\
-					./classes/Elements/SegRef.cpp\
-					./classes/Elements/Tria.cpp\
-					./classes/Elements/TriaRef.cpp\
-					./classes/Elements/Tetra.cpp\
-					./classes/Elements/TetraRef.cpp\
-					./classes/Elements/Penta.cpp\
-					./classes/Elements/PentaRef.cpp\
-					./classes/Materials/Materials.cpp\
-					./classes/Materials/Matice.cpp\
-					./classes/Materials/Matlitho.cpp\
-					./classes/Materials/Matestar.cpp\
-					./classes/Constraints/Constraints.cpp\
-					./classes/Constraints/SpcStatic.cpp\
-					./classes/Constraints/SpcDynamic.cpp\
-					./classes/Loads/Channel.cpp\
-					./classes/Loads/Loads.cpp\
-					./classes/Loads/Penpair.cpp\
-					./classes/Loads/Pengrid.cpp\
-					./classes/Loads/Moulin.cpp\
-					./classes/Loads/Numericalflux.cpp\
-					./classes/Loads/Neumannflux.cpp\
-					./classes/matrix/ElementMatrix.cpp\
-					./classes/matrix/ElementVector.cpp\
-					./classes/Params/Parameters.cpp\
-					./classes/Params/BoolParam.cpp\
-					./classes/Params/IntParam.cpp\
-					./classes/Params/IntVecParam.cpp\
-					./classes/Params/IntMatParam.cpp\
-					./classes/Params/DoubleParam.cpp\
-					./classes/Params/FileParam.cpp\
-					./classes/Params/StringArrayParam.cpp\
-					./classes/Params/DoubleMatParam.cpp\
-					./classes/Params/DoubleTransientMatParam.cpp\
-					./classes/Params/DoubleMatArrayParam.cpp\
-					./classes/Params/DoubleVecParam.cpp\
-					./classes/Params/StringParam.cpp\
-					./classes/Params/MatrixParam.cpp\
-					./classes/Params/VectorParam.cpp\
-					./classes/Params/TransientParam.cpp\
-					./classes/Params/TransientArrayParam.cpp\
-					./classes/Params/DataSetParam.cpp\
-					./classes/Profiler.cpp\
-					./shared/Matrix/MatrixUtils.cpp\
-					./shared/io/Disk/pfopen.cpp\
-					./shared/io/Disk/pfclose.cpp\
-					./shared/io/Disk/WriteLockFile.cpp\
-					./shared/io/Print/PrintfFunction.cpp\
-					./shared/io/Comm/IssmComm.cpp\
-					./shared/io/Marshalling/IoCodeConversions.cpp \
-					./shared/LatLong/Ll2xyx.cpp\
-					./shared/LatLong/Xy2llx.cpp\
-					./shared/FSanalyticals/fsanalyticals.cpp\
-					./shared/Enum/EnumToStringx.cpp\
-					./shared/Enum/StringToEnumx.cpp\
-					./shared/Numerics/Verbosity.cpp\
-					./shared/Numerics/GaussPoints.cpp\
-					./shared/Numerics/cross.cpp\
-					./shared/Numerics/cubic.cpp\
-					./shared/Numerics/NewtonSolveDnorm.cpp\
-					./shared/Numerics/ODE1.cpp\
-					./shared/Numerics/extrema.cpp\
-					./shared/Numerics/legendre.cpp\
-					./shared/Numerics/XZvectorsToCoordinateSystem.cpp\
-					./shared/Exceptions/Exceptions.cpp\
-					./shared/Sorting/binary_search.cpp\
-					./shared/Elements/Cuffey.cpp\
-					./shared/Elements/BuddJacka.cpp\
-					./shared/Elements/CuffeyTemperate.cpp\
-					./shared/Elements/StressIntensityIntegralWeight.cpp\
-					./shared/Elements/Paterson.cpp\
-					./shared/Elements/Arrhenius.cpp\
-					./shared/Elements/NyeCO2.cpp\
-					./shared/Elements/NyeH2O.cpp\
-					./shared/Elements/LliboutryDuval.cpp \
-					./shared/Elements/PrintArrays.cpp\
-					./shared/Elements/PddSurfaceMassBalance.cpp\
-					./shared/Elements/PddSurfaceMassBalanceSicopolis.cpp\
-					./shared/Elements/ComputeDelta18oTemperaturePrecipitation.cpp\
-					./shared/Elements/ComputeMungsmTemperaturePrecipitation.cpp\
-					./shared/Elements/ComputeD18OTemperaturePrecipitationFromPD.cpp\
-					./shared/Elements/DrainageFunctionWaterfraction.cpp\
-					./shared/Elements/EstarComponents.cpp\
-					./shared/String/DescriptorIndex.cpp\
-					./toolkits/issm/IssmToolkitUtils.cpp\
-					./toolkits/issm/IssmSolver.cpp\
-					./toolkits/mpi/issmmpi.cpp\
-					./toolkits/mpi/commops/DetermineLocalSize.cpp\
-					./toolkits/mpi/commops/DetermineGlobalSize.cpp\
-					./toolkits/mpi/commops/DetermineRowRankFromLocalSize.cpp\
-					./toolkits/mpi/commops/GetOwnershipBoundariesFromRange.cpp\
-					./toolkits/ToolkitOptions.cpp\
-					./modules/ModelProcessorx/ModelProcessorx.cpp\
-					./modules/ModelProcessorx/ElementsAndVerticesPartitioning.cpp\
-					./modules/ModelProcessorx/NodesPartitioning.cpp\
-					./modules/ModelProcessorx/EdgesPartitioning.cpp\
-					./modules/ModelProcessorx/FacesPartitioning.cpp\
-					./modules/ModelProcessorx/CreateParameters.cpp\
-					./modules/ModelProcessorx/Autodiff/CreateParametersAutodiff.cpp\
-					./modules/ModelProcessorx/CreateFaces.cpp\
-					./modules/ModelProcessorx/CreateEdges.cpp\
-					./modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp\
-					./modules/ModelProcessorx/CreateNumberNodeToElementConnectivity.cpp\
-					./modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp\
-					./modules/ModelProcessorx/CreateNodes.cpp\
-					./modules/ParseToolkitsOptionsx/ParseToolkitsOptionsx.cpp\
-					./modules/NodesDofx/NodesDofx.cpp\
-					./modules/NodalValuex/NodalValuex.cpp\
-					./modules/VertexCoordinatesx/VertexCoordinatesx.cpp\
-					./modules/OutputResultsx/OutputResultsx.cpp\
-					./modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.cpp\
-					./modules/InputDuplicatex/InputDuplicatex.cpp\
-					./modules/InputExtrudex/InputExtrudex.cpp\
-					./modules/SurfaceAreax/SurfaceAreax.cpp\
-					./modules/AllocateSystemMatricesx/AllocateSystemMatricesx.cpp\
-					./modules/CreateJacobianMatrixx/CreateJacobianMatrixx.cpp\
-					./modules/SystemMatricesx/SystemMatricesx.cpp\
-					./modules/CreateNodalConstraintsx/CreateNodalConstraintsx.cpp\
-					./modules/UpdateDynamicConstraintsx/UpdateDynamicConstraintsx.cpp\
-					./modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp\
-					./modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp\
-					./modules/InputUpdateFromConstantx/InputUpdateFromConstantx.cpp\
-					./modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.cpp\
-					./modules/GeothermalFluxx/GeothermalFluxx.cpp\
-					./modules/GetSolutionFromInputsx/GetSolutionFromInputsx.cpp\
-					./modules/GetVectorFromInputsx/GetVectorFromInputsx.cpp\
-					./modules/InputUpdateFromVectorx/InputUpdateFromVectorx.cpp\
-					./modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp\
-					./modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp\
-					./modules/FrontalForcingsx/FrontalForcingsx.cpp\
-					./modules/ConfigureObjectsx/ConfigureObjectsx.cpp\
-					./modules/SpcNodesx/SpcNodesx.cpp\
-					./modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp\
-					./modules/SurfaceMassBalancex/Gembx.cpp\
-					./modules/Reducevectorgtofx/Reducevectorgtofx.cpp\
-					./modules/Reduceloadx/Reduceloadx.cpp\
-					./modules/ConstraintsStatex/ConstraintsStatex.cpp\
-					./modules/ResetConstraintsx/ResetConstraintsx.cpp\
-					./modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.cpp\
-					./modules/Solverx/Solverx.cpp\
-					./modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp\
-					./cores/ProcessArguments.cpp\
-					./cores/ResetBoundaryConditions.cpp\
-					./cores/WrapperCorePointerFromSolutionEnum.cpp\
-					./cores/CorePointerFromSolutionEnum.cpp\
-					./cores/ad_core.cpp\
-					./cores/adgradient_core.cpp\
-					./main/EnvironmentInit.cpp\
-					./main/EnvironmentFinalize.cpp\
-					./analyses/EnumToAnalysis.cpp\
-					./solutionsequences/solutionsequence_la.cpp\
-					./solutionsequences/solutionsequence_la_theta.cpp\
-					./solutionsequences/solutionsequence_linear.cpp\
-					./solutionsequences/solutionsequence_nonlinear.cpp\
-					./solutionsequences/solutionsequence_newton.cpp\
-					./solutionsequences/solutionsequence_fct.cpp\
-					./solutionsequences/solutionsequence_schurcg.cpp\
-					./solutionsequences/convergence.cpp\
-					./classes/Options/Options.cpp\
-					./classes/Options/OptionUtilities.cpp\
-					./classes/RiftStruct.cpp\
-					./modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp \
-					./cores/transient_core.cpp\
-					./cores/steadystate_core.cpp\
-					./cores/masstransport_core.cpp\
-					./cores/depthaverage_core.cpp\
-					./cores/extrudefrombase_core.cpp\
-					./cores/extrudefromtop_core.cpp\
-					./cores/thermal_core.cpp\
-					./cores/smb_core.cpp\
-					./cores/bmb_core.cpp\
-					./solutionsequences/solutionsequence_thermal_nonlinear.cpp\
-					./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp\
-					./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp\
-					./modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp\
-					./modules/ModelProcessorx/Control/CreateParametersControl.cpp\
-					./modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp\
-					./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp\
-					./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp\
-					./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp\
-					./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp\
-					./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp\
-					./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp\
-					./modules/Gradjx/Gradjx.cpp\
-					./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp\
-					./modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp\
-					./modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp\
-					./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp\
-					./modules/RheologyBAbsGradientx/RheologyBAbsGradientx.cpp\
-					./shared/Numerics/BrentSearch.cpp\
-					./cores/control_core.cpp\
-					./cores/controltao_core.cpp\
-					./cores/controlm1qn3_core.cpp\
-					./cores/controladm1qn3_core.cpp\
-					./cores/controlvalidation_core.cpp\
-					./cores/adjointstressbalance_core.cpp\
-					./cores/adjointbalancethickness_core.cpp\
-					./cores/adjointbalancethickness2_core.cpp\
-					./cores/AdjointCorePointerFromSolutionEnum.cpp\
-					./solutionsequences/solutionsequence_adjoint_linear.cpp\
-					./cores/hydrology_core.cpp\
-					./solutionsequences/solutionsequence_hydro_nonlinear.cpp\
-					./solutionsequences/solutionsequence_shakti_nonlinear.cpp\
-					./solutionsequences/solutionsequence_glads_nonlinear.cpp\
-					./cores/stressbalance_core.cpp\
-					./solutionsequences/solutionsequence_stokescoupling_nonlinear.cpp\
-					./cores/balancethickness_core.cpp \
-					./cores/balancethickness2_core.cpp \
-					./cores/balancevelocity_core.cpp \
-					./cores/dummy_core.cpp\
-					./cores/surfaceslope_core.cpp\
-					./cores/bedslope_core.cpp\
-					./cores/damage_core.cpp\
-					./cores/levelsetfunctionslope_core.cpp\
-					./cores/movingfront_core.cpp\
-					./modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp\
-					./classes/Loads/Riftfront.cpp\
-					./modules/ConstraintsStatex/RiftConstraintsState.cpp\
-					./modules/ModelProcessorx/CreateOutputDefinitions.cpp\
-					./modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.cpp\
-					./modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp\
-					./classes/Inputs2/Inputs2.cpp\
-					./classes/Inputs2/BoolInput2.cpp\
-					./classes/Inputs2/IntInput2.cpp\
-					./classes/Inputs2/ElementInput2.cpp\
-					./classes/Inputs2/SegInput2.cpp\
-					./classes/Inputs2/TriaInput2.cpp\
-					./classes/Inputs2/PentaInput2.cpp\
-					./classes/Inputs2/DatasetInput2.cpp\
-					./classes/Inputs2/ControlInput2.cpp\
-					./classes/Inputs2/TransientInput2.cpp\
-					./classes/Inputs2/ArrayInput2.cpp
+issm_sources += \
+	./datastructures/DataSet.cpp \
+	./classes/gauss/GaussSeg.cpp \
+	./classes/gauss/GaussTria.cpp \
+	./classes/gauss/GaussTetra.cpp \
+	./classes/gauss/GaussPenta.cpp \
+	./classes/IoModel.cpp \
+	./classes/FemModel.cpp \
+	./classes/Loads/Friction.cpp \
+	./classes/Constraints/SpcTransient.cpp \
+	./classes/DependentObject.cpp \
+	./classes/Contours.cpp \
+	./classes/Vertices.cpp \
+	./classes/Nodes.cpp \
+	./classes/Numberedcostfunction.cpp \
+	./classes/Misfit.cpp \
+	./classes/Cfsurfacesquare.cpp \
+	./classes/Cfdragcoeffabsgrad.cpp \
+	./classes/Cfsurfacelogvel.cpp \
+	./classes/Regionaloutput.cpp \
+	./classes/Nodalvalue.cpp \
+	./classes/Node.cpp \
+	./classes/Vertex.cpp \
+	./classes/Hook.cpp \
+	./classes/Radar.cpp \
+	./classes/ExternalResults/Results.cpp \
+	./classes/Elements/Element.cpp \
+	./classes/Elements/Elements.cpp \
+	./classes/Elements/ElementHook.cpp \
+	./classes/Elements/Seg.cpp \
+	./classes/Elements/SegRef.cpp \
+	./classes/Elements/Tria.cpp \
+	./classes/Elements/TriaRef.cpp \
+	./classes/Elements/Tetra.cpp \
+	./classes/Elements/TetraRef.cpp \
+	./classes/Elements/Penta.cpp \
+	./classes/Elements/PentaRef.cpp \
+	./classes/Materials/Materials.cpp \
+	./classes/Materials/Matice.cpp \
+	./classes/Materials/Matlitho.cpp \
+	./classes/Materials/Matestar.cpp \
+	./classes/Constraints/Constraints.cpp \
+	./classes/Constraints/SpcStatic.cpp \
+	./classes/Constraints/SpcDynamic.cpp \
+	./classes/Loads/Channel.cpp \
+	./classes/Loads/Loads.cpp \
+	./classes/Loads/Penpair.cpp \
+	./classes/Loads/Pengrid.cpp \
+	./classes/Loads/Moulin.cpp \
+	./classes/Loads/Numericalflux.cpp \
+	./classes/Loads/Neumannflux.cpp \
+	./classes/matrix/ElementMatrix.cpp \
+	./classes/matrix/ElementVector.cpp \
+	./classes/Params/Parameters.cpp \
+	./classes/Params/BoolParam.cpp \
+	./classes/Params/IntParam.cpp \
+	./classes/Params/IntVecParam.cpp \
+	./classes/Params/IntMatParam.cpp \
+	./classes/Params/DoubleParam.cpp \
+	./classes/Params/FileParam.cpp \
+	./classes/Params/StringArrayParam.cpp \
+	./classes/Params/DoubleMatParam.cpp \
+	./classes/Params/DoubleTransientMatParam.cpp \
+	./classes/Params/DoubleMatArrayParam.cpp \
+	./classes/Params/DoubleVecParam.cpp \
+	./classes/Params/StringParam.cpp \
+	./classes/Params/MatrixParam.cpp \
+	./classes/Params/VectorParam.cpp \
+	./classes/Params/TransientParam.cpp \
+	./classes/Params/TransientArrayParam.cpp \
+	./classes/Params/DataSetParam.cpp \
+	./classes/Profiler.cpp \
+	./shared/Matrix/MatrixUtils.cpp \
+	./shared/io/Disk/pfopen.cpp \
+	./shared/io/Disk/pfclose.cpp \
+	./shared/io/Disk/WriteLockFile.cpp \
+	./shared/io/Print/PrintfFunction.cpp \
+	./shared/io/Comm/IssmComm.cpp \
+	./shared/io/Marshalling/IoCodeConversions.cpp \
+	./shared/LatLong/Ll2xyx.cpp \
+	./shared/LatLong/Xy2llx.cpp \
+	./shared/FSanalyticals/fsanalyticals.cpp \
+	./shared/Enum/EnumToStringx.cpp \
+	./shared/Enum/StringToEnumx.cpp \
+	./shared/Numerics/Verbosity.cpp \
+	./shared/Numerics/GaussPoints.cpp \
+	./shared/Numerics/cross.cpp \
+	./shared/Numerics/cubic.cpp \
+	./shared/Numerics/NewtonSolveDnorm.cpp \
+	./shared/Numerics/ODE1.cpp \
+	./shared/Numerics/extrema.cpp \
+	./shared/Numerics/legendre.cpp \
+	./shared/Numerics/XZvectorsToCoordinateSystem.cpp \
+	./shared/Exceptions/Exceptions.cpp \
+	./shared/Sorting/binary_search.cpp \
+	./shared/Elements/Cuffey.cpp \
+	./shared/Elements/BuddJacka.cpp \
+	./shared/Elements/CuffeyTemperate.cpp \
+	./shared/Elements/StressIntensityIntegralWeight.cpp \
+	./shared/Elements/Paterson.cpp \
+	./shared/Elements/Arrhenius.cpp \
+	./shared/Elements/NyeCO2.cpp \
+	./shared/Elements/NyeH2O.cpp \
+	./shared/Elements/LliboutryDuval.cpp \
+	./shared/Elements/PrintArrays.cpp \
+	./shared/Elements/PddSurfaceMassBalance.cpp \
+	./shared/Elements/PddSurfaceMassBalanceSicopolis.cpp \
+	./shared/Elements/ComputeDelta18oTemperaturePrecipitation.cpp \
+	./shared/Elements/ComputeMungsmTemperaturePrecipitation.cpp \
+	./shared/Elements/ComputeD18OTemperaturePrecipitationFromPD.cpp \
+	./shared/Elements/DrainageFunctionWaterfraction.cpp \
+	./shared/Elements/EstarComponents.cpp \
+	./shared/String/DescriptorIndex.cpp \
+	./toolkits/issm/IssmToolkitUtils.cpp \
+	./toolkits/issm/IssmSolver.cpp \
+	./toolkits/mpi/issmmpi.cpp \
+	./toolkits/mpi/commops/DetermineLocalSize.cpp \
+	./toolkits/mpi/commops/DetermineGlobalSize.cpp \
+	./toolkits/mpi/commops/DetermineRowRankFromLocalSize.cpp \
+	./toolkits/mpi/commops/GetOwnershipBoundariesFromRange.cpp \
+	./toolkits/ToolkitOptions.cpp \
+	./modules/ModelProcessorx/ModelProcessorx.cpp \
+	./modules/ModelProcessorx/ElementsAndVerticesPartitioning.cpp \
+	./modules/ModelProcessorx/NodesPartitioning.cpp \
+	./modules/ModelProcessorx/EdgesPartitioning.cpp \
+	./modules/ModelProcessorx/FacesPartitioning.cpp \
+	./modules/ModelProcessorx/CreateParameters.cpp \
+	./modules/ModelProcessorx/Autodiff/CreateParametersAutodiff.cpp \
+	./modules/ModelProcessorx/CreateFaces.cpp \
+	./modules/ModelProcessorx/CreateEdges.cpp \
+	./modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp \
+	./modules/ModelProcessorx/CreateNumberNodeToElementConnectivity.cpp \
+	./modules/ModelProcessorx/CreateElementsVerticesAndMaterials.cpp \
+	./modules/ModelProcessorx/CreateNodes.cpp \
+	./modules/ParseToolkitsOptionsx/ParseToolkitsOptionsx.cpp \
+	./modules/NodesDofx/NodesDofx.cpp \
+	./modules/NodalValuex/NodalValuex.cpp \
+	./modules/VertexCoordinatesx/VertexCoordinatesx.cpp \
+	./modules/OutputResultsx/OutputResultsx.cpp \
+	./modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.cpp \
+	./modules/InputDuplicatex/InputDuplicatex.cpp \
+	./modules/InputExtrudex/InputExtrudex.cpp \
+	./modules/SurfaceAreax/SurfaceAreax.cpp \
+	./modules/AllocateSystemMatricesx/AllocateSystemMatricesx.cpp \
+	./modules/CreateJacobianMatrixx/CreateJacobianMatrixx.cpp \
+	./modules/SystemMatricesx/SystemMatricesx.cpp \
+	./modules/CreateNodalConstraintsx/CreateNodalConstraintsx.cpp \
+	./modules/UpdateDynamicConstraintsx/UpdateDynamicConstraintsx.cpp \
+	./modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp \
+	./modules/SetActiveNodesLSMx/SetActiveNodesLSMx.cpp \
+	./modules/InputUpdateFromConstantx/InputUpdateFromConstantx.cpp \
+	./modules/InputUpdateFromSolutionx/InputUpdateFromSolutionx.cpp \
+	./modules/GeothermalFluxx/GeothermalFluxx.cpp \
+	./modules/GetSolutionFromInputsx/GetSolutionFromInputsx.cpp \
+	./modules/GetVectorFromInputsx/GetVectorFromInputsx.cpp \
+	./modules/InputUpdateFromVectorx/InputUpdateFromVectorx.cpp \
+	./modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp \
+	./modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp \
+	./modules/FrontalForcingsx/FrontalForcingsx.cpp \
+	./modules/ConfigureObjectsx/ConfigureObjectsx.cpp \
+	./modules/SpcNodesx/SpcNodesx.cpp \
+	./modules/SurfaceMassBalancex/SurfaceMassBalancex.cpp \
+	./modules/SurfaceMassBalancex/Gembx.cpp \
+	./modules/Reducevectorgtofx/Reducevectorgtofx.cpp \
+	./modules/Reduceloadx/Reduceloadx.cpp \
+	./modules/ConstraintsStatex/ConstraintsStatex.cpp \
+	./modules/ResetConstraintsx/ResetConstraintsx.cpp \
+	./modules/ResetFSBasalBoundaryConditionx/ResetFSBasalBoundaryConditionx.cpp \
+	./modules/Solverx/Solverx.cpp \
+	./modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp \
+	./cores/ProcessArguments.cpp \
+	./cores/ResetBoundaryConditions.cpp \
+	./cores/WrapperCorePointerFromSolutionEnum.cpp \
+	./cores/CorePointerFromSolutionEnum.cpp \
+	./cores/ad_core.cpp \
+	./cores/adgradient_core.cpp \
+	./main/EnvironmentInit.cpp \
+	./main/EnvironmentFinalize.cpp \
+	./analyses/EnumToAnalysis.cpp \
+	./solutionsequences/solutionsequence_la.cpp \
+	./solutionsequences/solutionsequence_la_theta.cpp \
+	./solutionsequences/solutionsequence_linear.cpp \
+	./solutionsequences/solutionsequence_nonlinear.cpp \
+	./solutionsequences/solutionsequence_newton.cpp \
+	./solutionsequences/solutionsequence_fct.cpp \
+	./solutionsequences/solutionsequence_schurcg.cpp \
+	./solutionsequences/convergence.cpp \
+	./classes/Options/Options.cpp \
+	./classes/Options/OptionUtilities.cpp \
+	./classes/RiftStruct.cpp \
+	./modules/ModelProcessorx/Transient/UpdateElementsTransient.cpp \
+	./cores/transient_core.cpp \
+	./cores/steadystate_core.cpp \
+	./cores/masstransport_core.cpp \
+	./cores/depthaverage_core.cpp \
+	./cores/extrudefrombase_core.cpp \
+	./cores/extrudefromtop_core.cpp \
+	./cores/thermal_core.cpp \
+	./cores/smb_core.cpp \
+	./cores/bmb_core.cpp \
+	./solutionsequences/solutionsequence_thermal_nonlinear.cpp \
+	./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp \
+	./modules/GetVectorFromControlInputsx/GetVectorFromControlInputsx.cpp \
+	./modules/SetControlInputsFromVectorx/SetControlInputsFromVectorx.cpp \
+	./modules/ModelProcessorx/Control/CreateParametersControl.cpp \
+	./modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp \
+	./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp \
+	./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp \
+	./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp \
+	./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp \
+	./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp \
+	./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp \
+	./modules/Gradjx/Gradjx.cpp \
+	./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp \
+	./modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp \
+	./modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp \
+	./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp \
+	./modules/RheologyBAbsGradientx/RheologyBAbsGradientx.cpp \
+	./shared/Numerics/BrentSearch.cpp \
+	./cores/control_core.cpp \
+	./cores/controltao_core.cpp \
+	./cores/controlm1qn3_core.cpp \
+	./cores/controladm1qn3_core.cpp \
+	./cores/controlvalidation_core.cpp \
+	./cores/adjointstressbalance_core.cpp \
+	./cores/adjointbalancethickness_core.cpp \
+	./cores/adjointbalancethickness2_core.cpp \
+	./cores/AdjointCorePointerFromSolutionEnum.cpp \
+	./solutionsequences/solutionsequence_adjoint_linear.cpp \
+	./cores/hydrology_core.cpp \
+	./solutionsequences/solutionsequence_hydro_nonlinear.cpp \
+	./solutionsequences/solutionsequence_shakti_nonlinear.cpp \
+	./solutionsequences/solutionsequence_glads_nonlinear.cpp \
+	./cores/stressbalance_core.cpp \
+	./solutionsequences/solutionsequence_stokescoupling_nonlinear.cpp \
+	./cores/balancethickness_core.cpp \
+	./cores/balancethickness2_core.cpp \
+	./cores/balancevelocity_core.cpp \
+	./cores/dummy_core.cpp \
+	./cores/surfaceslope_core.cpp \
+	./cores/bedslope_core.cpp \
+	./cores/damage_core.cpp \
+	./cores/levelsetfunctionslope_core.cpp \
+	./cores/movingfront_core.cpp \
+	./modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp \
+	./classes/Loads/Riftfront.cpp \
+	./modules/ConstraintsStatex/RiftConstraintsState.cpp \
+	./modules/ModelProcessorx/CreateOutputDefinitions.cpp \
+	./modules/OutputDefinitionsResponsex/OutputDefinitionsResponsex.cpp \
+	./modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp \
+	./classes/Inputs2/Inputs2.cpp \
+	./classes/Inputs2/BoolInput2.cpp \
+	./classes/Inputs2/IntInput2.cpp \
+	./classes/Inputs2/ElementInput2.cpp \
+	./classes/Inputs2/SegInput2.cpp \
+	./classes/Inputs2/TriaInput2.cpp \
+	./classes/Inputs2/PentaInput2.cpp \
+	./classes/Inputs2/DatasetInput2.cpp \
+	./classes/Inputs2/ControlInput2.cpp \
+	./classes/Inputs2/TransientInput2.cpp \
+	./classes/Inputs2/ArrayInput2.cpp
 #}}}
 #ADJOINTMPI/MeDiPack sources {{{
@@ -337,34 +340,36 @@
 #DAKOTA sources  {{{
 if DAKOTA
-issm_sources +=  ./classes/Dakota/IssmDirectApplicInterface.h\
-					  ./classes/Dakota/IssmParallelDirectApplicInterface.cpp\
-					  ./modules/InputUpdateFromDakotax/InputUpdateFromDakotax.cpp\
-					  ./modules/InputUpdateFromVectorDakotax/InputUpdateFromVectorDakotax.cpp\
-					  ./modules/InputUpdateFromMatrixDakotax/InputUpdateFromMatrixDakotax.cpp\
-					  ./modules/AverageOntoPartitionx/AverageOntoPartitionx.cpp\
-					  ./modules/ModelProcessorx/Dakota/CreateParametersDakota.cpp\
-					  ./modules/ModelProcessorx/Dakota/UpdateElementsAndMaterialsDakota.cpp\
-					  ./cores/dakota_core.cpp
+issm_sources += \
+	./classes/Dakota/IssmDirectApplicInterface.h \
+	./classes/Dakota/IssmParallelDirectApplicInterface.cpp \
+	./modules/InputUpdateFromDakotax/InputUpdateFromDakotax.cpp \
+	./modules/InputUpdateFromVectorDakotax/InputUpdateFromVectorDakotax.cpp \
+	./modules/InputUpdateFromMatrixDakotax/InputUpdateFromMatrixDakotax.cpp \
+	./modules/AverageOntoPartitionx/AverageOntoPartitionx.cpp \
+	./modules/ModelProcessorx/Dakota/CreateParametersDakota.cpp \
+	./modules/ModelProcessorx/Dakota/UpdateElementsAndMaterialsDakota.cpp \
+	./cores/dakota_core.cpp
 endif
 #}}}
 #Petsc sources  {{{
 if PETSC
-issm_sources += ./toolkits/petsc\
-					./toolkits/petsc/patches\
-					./toolkits/petsc/patches/VecToMPISerial.cpp\
-					./toolkits/petsc/patches/MatToSerial.cpp\
-					./toolkits/petsc/patches/NewVec.cpp\
-					./toolkits/petsc/patches/PetscOptionsDetermineSolverType.cpp\
-					./toolkits/petsc/patches/NewMat.cpp\
-					./toolkits/petsc/patches/VecFree.cpp\
-					./toolkits/petsc/patches/KSPFree.cpp\
-					./toolkits/petsc/patches/MatFree.cpp\
-					./toolkits/petsc/patches/MatMultPatch.cpp\
-					./toolkits/petsc/patches/ISSMToPetscMatrixType.cpp\
-					./toolkits/petsc/patches/ISSMToPetscInsertMode.cpp\
-					./toolkits/petsc/patches/ISSMToPetscNormMode.cpp\
-					./toolkits/petsc/objects/PetscMat.cpp\
-					./toolkits/petsc/objects/PetscVec.cpp\
-					./toolkits/petsc/objects/PetscSolver.cpp
+issm_sources += \
+	./toolkits/petsc \
+	./toolkits/petsc/patches \
+	./toolkits/petsc/patches/VecToMPISerial.cpp \
+	./toolkits/petsc/patches/MatToSerial.cpp \
+	./toolkits/petsc/patches/NewVec.cpp \
+	./toolkits/petsc/patches/PetscOptionsDetermineSolverType.cpp \
+	./toolkits/petsc/patches/NewMat.cpp \
+	./toolkits/petsc/patches/VecFree.cpp \
+	./toolkits/petsc/patches/KSPFree.cpp \
+	./toolkits/petsc/patches/MatFree.cpp \
+	./toolkits/petsc/patches/MatMultPatch.cpp \
+	./toolkits/petsc/patches/ISSMToPetscMatrixType.cpp \
+	./toolkits/petsc/patches/ISSMToPetscInsertMode.cpp \
+	./toolkits/petsc/patches/ISSMToPetscNormMode.cpp \
+	./toolkits/petsc/objects/PetscMat.cpp \
+	./toolkits/petsc/objects/PetscVec.cpp \
+	./toolkits/petsc/objects/PetscSolver.cpp
 endif
 #}}}
@@ -492,49 +497,53 @@
 endif
 #}}}
-#Gia sources  (only if have fortran){{{
+#Gia sources (only if have fortran){{{
 if GIAIVINS
 if FORTRAN
-issm_sources +=  ./cores/gia_core.cpp\
-					./analyses/GiaIvinsAnalysis.cpp\
-					./modules/GiaDeflectionCorex/GiaDeflectionCorex.cpp\
-					./modules/GiaDeflectionCorex/distme.f\
-					./modules/GiaDeflectionCorex/freed.f\
-					./modules/GiaDeflectionCorex/ojrule.f\
-					./modules/GiaDeflectionCorex/pwise.f\
-					./modules/GiaDeflectionCorex/qwise.f\
-					./modules/GiaDeflectionCorex/stot.f\
-					./modules/GiaDeflectionCorex/what0.f
-endif
-endif
-#}}}
-#Love sources  (only if have fortran){{{
+issm_sources += \
+	./cores/gia_core.cpp \
+	./analyses/GiaIvinsAnalysis.cpp \
+	./modules/GiaDeflectionCorex/GiaDeflectionCorex.cpp \
+	./modules/GiaDeflectionCorex/distme.f \
+	./modules/GiaDeflectionCorex/freed.f \
+	./modules/GiaDeflectionCorex/ojrule.f \
+	./modules/GiaDeflectionCorex/pwise.f \
+	./modules/GiaDeflectionCorex/qwise.f \
+	./modules/GiaDeflectionCorex/stot.f \
+	./modules/GiaDeflectionCorex/what0.f
+endif
+endif
+#}}}
+#Love sources (only if have fortran){{{
 if LOVE
 if FORTRAN
-issm_sources +=  ./cores/love_core.cpp\
-				 ./analyses/LoveAnalysis.cpp\
-				./modules/FourierLoveCorex/FourierLoveCorex.cpp\
-				./modules/FourierLoveCorex/lnb_param.f90\
-				./modules/FourierLoveCorex/model.f90\
-				./modules/FourierLoveCorex/util.f90\
-				./modules/FourierLoveCorex/lovenb_sub.f90\
-				./modules/FourierLoveCorex/love_numbers.f90
+issm_sources += \
+	./cores/love_core.cpp \
+	./analyses/LoveAnalysis.cpp \
+	./modules/FourierLoveCorex/FourierLoveCorex.cpp \
+	./modules/FourierLoveCorex/lnb_param.f90 \
+	./modules/FourierLoveCorex/model.f90 \
+	./modules/FourierLoveCorex/util.f90 \
+	./modules/FourierLoveCorex/lovenb_sub.f90 \
+	./modules/FourierLoveCorex/love_numbers.f90
 endif
 endif
 #}}}
 #Esa sources  {{{
-if ESA 
-issm_sources +=  ./cores/esa_core.cpp\
-					./analyses/EsaAnalysis.cpp
+if ESA
+issm_sources += \
+	./cores/esa_core.cpp \
+	./analyses/EsaAnalysis.cpp
 endif
 #}}}
 #Oceansources  {{{
 if OCEAN
-issm_sources +=  ./modules/OceanExchangeDatax/OceanExchangeDatax.cpp
+issm_sources += ./modules/OceanExchangeDatax/OceanExchangeDatax.cpp
 endif
 #}}}
 #Slr sources  {{{
 if SEALEVELRISE
-issm_sources +=  ./cores/sealevelrise_core.cpp\
-				 ./analyses/SealevelriseAnalysis.cpp
+issm_sources += \
+	./cores/sealevelrise_core.cpp \
+	./analyses/SealevelriseAnalysis.cpp
 endif
 #}}}
@@ -558,37 +567,38 @@
 #Wrapper sources
 #Kml sources  {{{
-kml_sources = ./modules/Exp2Kmlx/Exp2Kmlx.cpp\
-				  ./modules/Kml2Expx/Kml2Expx.cpp\
-				  ./modules/Shp2Kmlx/Shp2Kmlx.cpp\
-				  ./modules/KMLFileReadx/KMLFileReadx.cpp\
-				  ./modules/KMLMeshWritex/KMLMeshWritex.cpp\
-				  ./modules/KMLOverlayx/KMLOverlayx.cpp\
-				  ./kml/KML_Attribute.cpp\
-				  ./kml/KML_Comment.cpp\
-				  ./kml/KML_ColorStyle.cpp\
-				  ./kml/KML_Container.cpp\
-				  ./kml/KML_Document.cpp\
-				  ./kml/KML_Feature.cpp\
-				  ./kml/KML_File.cpp\
-				  ./kml/KML_Folder.cpp\
-				  ./kml/KML_Geometry.cpp\
-				  ./kml/KML_GroundOverlay.cpp\
-				  ./kml/KML_Icon.cpp\
-				  ./kml/KML_LatLonBox.cpp\
-				  ./kml/KML_LinearRing.cpp\
-				  ./kml/KML_LineString.cpp\
-				  ./kml/KML_LineStyle.cpp\
-				  ./kml/KML_MultiGeometry.cpp\
-				  ./kml/KML_Object.cpp\
-				  ./kml/KML_Overlay.cpp\
-				  ./kml/KML_Point.cpp\
-				  ./kml/KML_Placemark.cpp\
-				  ./kml/KML_Polygon.cpp\
-				  ./kml/KML_PolyStyle.cpp\
-				  ./kml/KML_Style.cpp\
-				  ./kml/KML_StyleSelector.cpp\
-				  ./kml/KML_SubStyle.cpp\
-				  ./kml/KML_Unknown.cpp\
-				  ./kml/KMLFileReadUtils.cpp
+kml_sources = \
+	./modules/Exp2Kmlx/Exp2Kmlx.cpp \
+	./modules/Kml2Expx/Kml2Expx.cpp \
+	./modules/Shp2Kmlx/Shp2Kmlx.cpp \
+	./modules/KMLFileReadx/KMLFileReadx.cpp \
+	./modules/KMLMeshWritex/KMLMeshWritex.cpp \
+	./modules/KMLOverlayx/KMLOverlayx.cpp \
+	./kml/KML_Attribute.cpp \
+	./kml/KML_Comment.cpp \
+	./kml/KML_ColorStyle.cpp \
+	./kml/KML_Container.cpp \
+	./kml/KML_Document.cpp \
+	./kml/KML_Feature.cpp \
+	./kml/KML_File.cpp \
+	./kml/KML_Folder.cpp \
+	./kml/KML_Geometry.cpp \
+	./kml/KML_GroundOverlay.cpp \
+	./kml/KML_Icon.cpp \
+	./kml/KML_LatLonBox.cpp \
+	./kml/KML_LinearRing.cpp \
+	./kml/KML_LineString.cpp \
+	./kml/KML_LineStyle.cpp \
+	./kml/KML_MultiGeometry.cpp \
+	./kml/KML_Object.cpp \
+	./kml/KML_Overlay.cpp \
+	./kml/KML_Point.cpp \
+	./kml/KML_Placemark.cpp \
+	./kml/KML_Polygon.cpp \
+	./kml/KML_PolyStyle.cpp \
+	./kml/KML_Style.cpp \
+	./kml/KML_StyleSelector.cpp \
+	./kml/KML_SubStyle.cpp \
+	./kml/KML_Unknown.cpp \
+	./kml/KMLFileReadUtils.cpp
 #}}}
 #NEOPZ sources  {{{
@@ -596,40 +606,43 @@
 #}}}
 #Modules sources{{{
-modules_sources= ./shared/Threads/LaunchThread.cpp\
-			./shared/Threads/PartitionRange.cpp\
-			./shared/Exp/exp.cpp\
-			./shared/Triangle/AssociateSegmentToElement.cpp\
-			./shared/Triangle/GridInsideHole.cpp\
-			./shared/Triangle/OrderSegments.cpp\
-			./shared/Triangle/SplitMeshForRifts.cpp\
-			./shared/Triangle/TriangleUtils.cpp\
-			./modules/Trianglex/Trianglex.cpp\
-			./modules/ProcessRiftsx/ProcessRiftsx.cpp\
-			./modules/PointCloudFindNeighborsx/PointCloudFindNeighborsx.cpp\
-			./modules/PointCloudFindNeighborsx/PointCloudFindNeighborsxt.cpp\
-			./modules/InterpFromGridToMeshx/InterpFromGridToMeshx.cpp\
-			./modules/InterpFromMesh2dx/InterpFromMesh2dx.cpp\
-			./modules/InterpFromMesh2dx/InterpFromMesh2dxt.cpp\
-			./modules/InterpFromMeshToMesh3dx/InterpFromMeshToMesh3dx.cpp\
-			./modules/InterpFromMeshToGridx/InterpFromMeshToGridx.cpp\
-			./modules/MeshProfileIntersectionx/MeshProfileIntersectionx.cpp\
-			./modules/ContourToMeshx/ContourToMeshx.cpp\
-			./modules/ContourToMeshx/ContourToMeshxt.cpp\
-			./modules/ExpToLevelSetx/ExpToLevelSetx.cpp\
-			./modules/ExpToLevelSetx/ExpToLevelSetxt.cpp\
-			./modules/ContourToNodesx/ContourToNodesx.cpp\
-			./modules/DistanceToMaskBoundaryx/DistanceToMaskBoundaryx.cpp\
-			./modules/DistanceToMaskBoundaryx/DistanceToMaskBoundaryxt.cpp\
-			./modules/NodeConnectivityx/NodeConnectivityx.cpp\
-			./modules/ElementConnectivityx/ElementConnectivityx.cpp\
-			./modules/PropagateFlagsFromConnectivityx/PropagateFlagsFromConnectivityx.cpp
+modules_sources = \
+	./shared/Threads/LaunchThread.cpp \
+	./shared/Threads/PartitionRange.cpp \
+	./shared/Exp/exp.cpp \
+	./shared/Triangle/AssociateSegmentToElement.cpp \
+	./shared/Triangle/GridInsideHole.cpp \
+	./shared/Triangle/OrderSegments.cpp \
+	./shared/Triangle/SplitMeshForRifts.cpp \
+	./shared/Triangle/TriangleUtils.cpp \
+	./modules/Trianglex/Trianglex.cpp \
+	./modules/ProcessRiftsx/ProcessRiftsx.cpp \
+	./modules/PointCloudFindNeighborsx/PointCloudFindNeighborsx.cpp \
+	./modules/PointCloudFindNeighborsx/PointCloudFindNeighborsxt.cpp \
+	./modules/InterpFromGridToMeshx/InterpFromGridToMeshx.cpp \
+	./modules/InterpFromMesh2dx/InterpFromMesh2dx.cpp \
+	./modules/InterpFromMesh2dx/InterpFromMesh2dxt.cpp \
+	./modules/InterpFromMeshToMesh3dx/InterpFromMeshToMesh3dx.cpp \
+	./modules/InterpFromMeshToGridx/InterpFromMeshToGridx.cpp \
+	./modules/MeshProfileIntersectionx/MeshProfileIntersectionx.cpp \
+	./modules/ContourToMeshx/ContourToMeshx.cpp \
+	./modules/ContourToMeshx/ContourToMeshxt.cpp \
+	./modules/ExpToLevelSetx/ExpToLevelSetx.cpp \
+	./modules/ExpToLevelSetx/ExpToLevelSetxt.cpp \
+	./modules/ContourToNodesx/ContourToNodesx.cpp \
+	./modules/DistanceToMaskBoundaryx/DistanceToMaskBoundaryx.cpp \
+	./modules/DistanceToMaskBoundaryx/DistanceToMaskBoundaryxt.cpp \
+	./modules/NodeConnectivityx/NodeConnectivityx.cpp \
+	./modules/ElementConnectivityx/ElementConnectivityx.cpp \
+	./modules/PropagateFlagsFromConnectivityx/PropagateFlagsFromConnectivityx.cpp
+
 if CHACO
-modules_sources+= ./modules/Chacox/Chacox.cpp\
-						./modules/Chacox/input_parse.cpp\
-						./modules/Chacox/chaco_seconds.cpp\
-						./modules/Chacox/user_params.cpp
+modules_sources += \
+	./modules/Chacox/Chacox.cpp \
+	./modules/Chacox/input_parse.cpp \
+	./modules/Chacox/chaco_seconds.cpp \
+	./modules/Chacox/user_params.cpp
 endif
 if SCOTCH
-modules_sources+= ./modules/Scotchx/Scotchx.cpp
+modules_sources += ./modules/Scotchx/Scotchx.cpp
 endif
 #}}}
@@ -638,20 +651,22 @@
 #Kriging sources  {{{
 if KRIGING
-issm_sources += ./classes/kriging/Observations.cpp\
-					./classes/kriging/GaussianVariogram.cpp\
-					./classes/kriging/ExponentialVariogram.cpp\
-					./classes/kriging/SphericalVariogram.cpp\
-					./classes/kriging/PowerVariogram.cpp\
-					./classes/kriging/Quadtree.cpp\
-					./classes/kriging/Covertree.cpp\
-					./classes/kriging/Observation.cpp\
-					./modules/Krigingx/pKrigingx.cpp
-
-modules_sources +=./modules/Krigingx/Krigingx.cpp\
-						./modules/Krigingx/pKrigingx.cpp
+issm_sources += \
+	./classes/kriging/Observations.cpp \
+	./classes/kriging/GaussianVariogram.cpp \
+	./classes/kriging/ExponentialVariogram.cpp \
+	./classes/kriging/SphericalVariogram.cpp \
+	./classes/kriging/PowerVariogram.cpp \
+	./classes/kriging/Quadtree.cpp \
+	./classes/kriging/Covertree.cpp \
+	./classes/kriging/Observation.cpp \
+	./modules/Krigingx/pKrigingx.cpp
+
+modules_sources += \
+	./modules/Krigingx/Krigingx.cpp \
+	./modules/Krigingx/pKrigingx.cpp
 endif
 #}}}
 #Library flags and sources {{{
-ALLCXXFLAGS= $(CXXFLAGS) $(CXXOPTFLAGS) 
+ALLCXXFLAGS= $(CXXFLAGS) $(CXXOPTFLAGS)
 
 libISSMCore_la_SOURCES  = $(issm_sources)
@@ -661,5 +676,5 @@
 if !WINDOWS
 if !STANDALONE_LIBRARIES
-libISSMCore_la_LIBADD = $(PETSCLIB) $(TAOLIB) $(M1QN3LIB) $(SEMICLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB)   $(ADOLCLIB) $(AMPILIB) $(ADJOINTMPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
+libISSMCore_la_LIBADD = $(PETSCLIB) $(TAOLIB) $(M1QN3LIB) $(SEMICLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(ADOLCLIB) $(AMPILIB) $(ADJOINTMPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
 if FORTRAN
 libISSMCore_la_LIBADD += $(FLIBS) $(FORTRANLIB)
@@ -699,5 +714,5 @@
 
 if STANDALONE_EXECUTABLES
-issm_LDFLAGS = -static
+AM_LDFLAGS += -static -Wl,--disable-new-dtags -Wl,-rpath,'$$ORIGIN/../lib'
 endif
 
@@ -708,8 +723,8 @@
 libISSMModules_la_LDFLAGS = -static
 else
-libISSMModules_la_LDFLAGS = 
-endif
-else
-libISSMCore_la_LDFLAGS = 
+libISSMModules_la_LDFLAGS =
+endif
+else
+libISSMCore_la_LDFLAGS =
 libISSMOverload_la_LDFLAGS =
 endif
@@ -724,7 +739,7 @@
 if ANDROID
 if ANDROIDEXE
-bin_PROGRAMS = issm  issm_slr
-else
-bin_PROGRAMS = 
+bin_PROGRAMS = issm issm_slr
+else
+bin_PROGRAMS =
 endif
 else
@@ -732,5 +747,5 @@
 bin_PROGRAMS =
 else
-bin_PROGRAMS = issm  issm_slr
+bin_PROGRAMS = issm issm_slr
 endif
 endif
@@ -743,5 +758,5 @@
 
 #External packages
-LDADD +=  $(NEOPZLIB) $(TAOLIB) $(M1QN3LIB) $(SEMICLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(PETSCLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB)  $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(AMPILIB) $(ADJOINTMPILIB) $(ADOLCLIB) $(MPILIB) $(METEOIOLIB) $(SNOWPACKLIB) $(PROJ4LIB)
+LDADD += $(NEOPZLIB) $(TAOLIB) $(M1QN3LIB) $(SEMICLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(PETSCLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(AMPILIB) $(ADJOINTMPILIB) $(ADOLCLIB) $(MPILIB) $(METEOIOLIB) $(SNOWPACKLIB) $(PROJ4LIB)
 
 if FORTRAN
@@ -764,5 +779,5 @@
 bin_PROGRAMS += kriging
 kriging_SOURCES = main/kriging.cpp
-kriging_CXXFLAGS= $(CXXFLAGS) $(CXXOPTFLAGS) $(COPTFLAGS) 
+kriging_CXXFLAGS= $(CXXFLAGS) $(CXXOPTFLAGS) $(COPTFLAGS)
 endif
 
@@ -770,5 +785,5 @@
 bin_PROGRAMS += issm_dakota
 issm_dakota_SOURCES = main/issm_dakota.cpp
-issm_dakota_CXXFLAGS= $(CXXFLAGS) $(CXXOPTFLAGS) $(COPTFLAGS) 
+issm_dakota_CXXFLAGS= $(CXXFLAGS) $(CXXOPTFLAGS) $(COPTFLAGS)
 issm_dakota_LDADD= $(LDADD)
 endif
Index: /issm/trunk-jpl/src/c/cores/dakota_core.cpp
===================================================================
--- /issm/trunk-jpl/src/c/cores/dakota_core.cpp	(revision 24592)
+++ /issm/trunk-jpl/src/c/cores/dakota_core.cpp	(revision 24593)
@@ -1,48 +1,48 @@
 /*!\file:  dakota_core.cpp
- * \brief: wrapper to the Dakota capabilities. qmu fires up Dakota, and registers a Dakota Pluggin
- * which will be in charge of running the solution sequences repeteadly, to garner statistics. 
- *
- * This routine deals with running ISSM and Dakota in library mode. In library mode, Dakota does not 
- * run as an execuatble. Its capabilities are linked into the ISSM software. ISSM calls dakota routines 
- * directly from the dakota library. qmu.cpp is the code that is in charge of calling those routines. 
- *
- * Dakota has its own way of running in parallel (for embarassingly parallel jobs). We do not want that, 
- * as ISSM knows exactly how to run "really parallel" jobs that use all CPUS. To bypass Dakota's parallelism, 
+ * \brief: wrapper to the Dakota capabilities. qmu fires up Dakota, and registers a Dakota Plugin
+ * which will be in charge of running the solution sequences repeatedly, to garner statistics.
+ *
+ * This routine deals with running ISSM and Dakota in library mode. In library mode, Dakota does not
+ * run as an executable. Its capabilities are linked into the ISSM software. ISSM calls Dakota routines
+ * directly from the Dakota library. qmu.cpp is the code that is in charge of calling those routines.
+ *
+ * Dakota has its own way of running in parallel (for embarrassingly parallel jobs). We do not want that,
+ * as ISSM knows exactly how to run "really parallel" jobs that use all CPUS. To bypass Dakota's parallelism,
  * we overloaded the constructor for the parallel library (see the Dakota patch in the externalpackages/dakota
- * directory). This overloaded constructor fires up Dakota serially on CPU 0 only! We take care of broadcasting 
- * to the other CPUS, hence ISSM is running in parallel, and Dakota serially on CPU0. 
- *
- * Now, how does CPU 0 drive all other CPUS to carry out sensitivity analysese? By synchronizing its call to 
- * our ISSM cores (stressbalance_core, thermal_core, transient_core, etc ...) on CPU 0 with all other CPUS. 
- * This explains the structure of qmu.cpp, where cpu 0 runs Dakota, the Dakota pluggin fires up DakotaSpawnCore.cpp, 
- * while the other CPUS are waiting for a broadcast from CPU0, once they get it, they also fire up 
- * DakotaSpawnCore. In the end, DakotaSpawnCore is fired up on all CPUS, with CPU0 having Dakota inputs, that it will 
- * broacast to other CPUS. 
- *
- * Now, how does dakota call the DakotaSpawnCore routine? The DakotaSpawnCore is embedded into the DakotaPlugin object 
- * which is derived from the Direct Interface Dakota objct. This is the only way to run Dakota in library 
- * mode (see their developper guide for more info). Dakota registers the DakotaPlugin object into its own 
- * database, and calls on the embedded DakotaSpawnCore from CPU0. 
- *
- */ 
+ * directory). This overloaded constructor fires up Dakota serially on CPU 0 only! We take care of broadcasting
+ * to the other CPUS, hence ISSM is running in parallel, and Dakota serially on CPU0.
+ *
+ * Now, how does CPU 0 drive all other CPUS to carry out sensitivity analyses? By synchronizing its call to
+ * our ISSM cores (stressbalance_core, thermal_core, transient_core, etc ...) on CPU 0 with all other CPUS.
+ * This explains the structure of qmu.cpp, where cpu 0 runs Dakota, the Dakota pluggin fires up DakotaSpawnCore.cpp,
+ * while the other CPUS are waiting for a broadcast from CPU0, once they get it, they also fire up
+ * DakotaSpawnCore. In the end, DakotaSpawnCore is fired up on all CPUS, with CPU0 having Dakota inputs, that it will
+ * broadcast to other CPUS.
+ *
+ * Now, how does Dakota call the DakotaSpawnCore routine? The DakotaSpawnCore is embedded into the DakotaPlugin object
+ * which is derived from the Direct Interface Dakota object. This is the only way to run Dakota in library
+ * mode (see their developer guide for more info). Dakota registers the DakotaPlugin object into its own
+ * database, and calls on the embedded DakotaSpawnCore from CPU0.
+ *
+ */
 
  /* \brief: run core ISSM solution using Dakota inputs coming from CPU 0.
  * \sa qmu.cpp DakotaPlugin.cpp
  *
- * This routine needs to be understood simultaneously with qmu.cpp and DakotaPlugin. 
- * DakotaSpawnCoreParallel is called by all CPUS, with CPU 0 holding Dakota variable values, along 
- * with variable descriptors. 
- *
- * DakotaSpawnCoreParallel takes care of broadcasting the variables and their descriptors across the MPI 
- * ring. Once this is done, we use the variables to modify the inputs for the solution core. 
- * For ex, if "rho_ice" is provided, for ex 920, we include "rho_ice" in the inputs, then 
- * call the core with the modified inputs. This is the way we get Dakota to explore the parameter 
- * spce of the core. 
- *
- * Once the core is called, we process the results of the core, and using the processed results, 
- * we compute response functions. The responses are computed on all CPUS, but they are targeted 
- * for CPU 0, which will get these values back to the Dakota engine. 
- *
- */ 
+ * This routine needs to be understood simultaneously with qmu.cpp and DakotaPlugin.
+ * DakotaSpawnCoreParallel is called by all CPUS, with CPU 0 holding Dakota variable values, along
+ * with variable descriptors.
+ *
+ * DakotaSpawnCoreParallel takes care of broadcasting the variables and their descriptors across the MPI
+ * ring. Once this is done, we use the variables to modify the inputs for the solution core.
+ * For ex, if "rho_ice" is provided, for ex 920, we include "rho_ice" in the inputs, then
+ * call the core with the modified inputs. This is the way we get Dakota to explore the parameter
+ * space of the core.
+ *
+ * Once the core is called, we process the results of the core, and using the processed results,
+ * we compute response functions. The responses are computed on all CPUS, but they are targeted
+ * for CPU 0, which will get these values back to the Dakota engine.
+ *
+ */
 
 /*include config: {{{*/
@@ -80,5 +80,5 @@
 void DakotaFree(double** pvariables,char*** pvariables_descriptors,char*** presponses_descriptors,int numvariables,int numresponses){ /*{{{*/
 
-	/*\brief DakotaFree: free allocations on other cpus, not done by Dakota.*/
+	/*\brief DakotaFree: free allocations on other CPUs, not done by Dakota.*/
 
 	int i;
@@ -98,5 +98,5 @@
 	my_rank=IssmComm::GetRank();
 
-	/*Free variables and variables_descriptors only on cpu !=0*/
+	/*Free variables and variables_descriptors only on CPU !=0*/
 	if(my_rank!=0){
 		xDelete<double>(variables);
@@ -108,5 +108,5 @@
 	}
 
-	//responses descriptors on every cpu
+	//responses descriptors on every CPU
 	for(i=0;i<numresponses;i++){
 		string=responses_descriptors[i];
@@ -124,6 +124,6 @@
 
 	/* * \brief: broadcast variables_descriptors, variables, numvariables and numresponses
-	 * from cpu 0 to all other cpus.
-	 */ 
+	 * from CPU 0 to all other CPUs.
+	 */
 
 	int i;
@@ -150,9 +150,9 @@
 
 	/*numvariables: */
-	ISSM_MPI_Bcast(&numvariables,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+	ISSM_MPI_Bcast(&numvariables,1,ISSM_MPI_INT,0,IssmComm::GetComm());
 
 	/*variables:*/
 	if(my_rank!=0)variables=xNew<double>(numvariables);
-	ISSM_MPI_Bcast(variables,numvariables,MPI_DOUBLE,0,IssmComm::GetComm()); 
+	ISSM_MPI_Bcast(variables,numvariables,MPI_DOUBLE,0,IssmComm::GetComm());
 
 	/*variables_descriptors: */
@@ -165,12 +165,12 @@
 			string_length=(strlen(string)+1)*sizeof(char);
 		}
-		ISSM_MPI_Bcast(&string_length,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+		ISSM_MPI_Bcast(&string_length,1,ISSM_MPI_INT,0,IssmComm::GetComm());
 		if(my_rank!=0)string=xNew<char>(string_length);
-		ISSM_MPI_Bcast(string,string_length,ISSM_MPI_CHAR,0,IssmComm::GetComm()); 
+		ISSM_MPI_Bcast(string,string_length,ISSM_MPI_CHAR,0,IssmComm::GetComm());
 		if(my_rank!=0)variables_descriptors[i]=string;
 	}
 
 	/*numresponses: */
-	ISSM_MPI_Bcast(&numresponses,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+	ISSM_MPI_Bcast(&numresponses,1,ISSM_MPI_INT,0,IssmComm::GetComm());
 
 	/*Assign output pointers:*/
@@ -182,5 +182,5 @@
 int  DakotaSpawnCore(double* d_responses, int d_numresponses, double* d_variables, char** d_variables_descriptors,int d_numvariables, void* void_femmodel,int counter){ /*{{{*/
 
-	/*Notice the d_, which prefixes anything that is being provided to us by the Dakota pluggin. Careful. some things are ours, some are dakotas!: */
+	/*Notice the d_, which prefixes anything that is being provided to us by the Dakota plugin. Careful: some things are ours; some are DDkota's!: */
 
 	char     **responses_descriptors    = NULL;      //these are our! there are only numresponsedescriptors of them, not d_numresponses!!!
@@ -192,10 +192,10 @@
 	bool       nodakotacore             = true;
 
-	/*If counter==-1 on cpu0, it means that the dakota runs are done. In which case, bail out and return 0: */
-	ISSM_MPI_Bcast(&counter,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+	/*If counter==-1 on CPU 0, it means that the Dakota runs are done. In which case, bail out and return 0: */
+	ISSM_MPI_Bcast(&counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());
 	if(counter==-1)return 0;
 
-	/*cast void_femmodel to FemModel, and at the same time, make a copy, so we start this new core run for this specific sample 
-	 *with a brand new copy of the model, which has not been tempered with by previous dakota runs: */
+	/*cast void_femmodel to FemModel, and at the same time, make a copy, so we start this new core run for this specific sample
+	 *with a brand new copy of the model, which has not been tempered with by previous Dakota runs: */
 	femmodel=(reinterpret_cast<FemModel*>(void_femmodel))->copy();
 
@@ -207,5 +207,5 @@
 	if(VerboseQmu()) _printf0_("qmu iteration: " << counter << "\n");
 
-	/* only cpu 0, running dakota is providing us with variables and variables_descriptors and numresponses: broadcast onto other cpus: */
+	/* only CPU 0, running Dakota is providing us with variables and variables_descriptors and numresponses: broadcast onto other CPUs: */
 	DakotaMPI_Bcast(&d_variables,&d_variables_descriptors,&d_numvariables,&d_numresponses);
 
@@ -231,5 +231,5 @@
 
 	return 1; //this is critical! do not return 0, otherwise, dakota_core will stop running!
-} 
+}
 /*}}}*/
 void dakota_core(FemModel* femmodel){  /*{{{*/
@@ -255,6 +255,6 @@
 		char* dakotamode=xNew<char>(strlen("serial")+1);
 		xMemCpy<char>(dakotamode,"serial",strlen("serial")+1);
-		Dakota::ParallelLibrary parallel_lib(dakotamode); //use our own ISSM Dakota library mode constructor, which only fires up Dakota on CPU 0. 
-		Dakota::ProblemDescDB problem_db(parallel_lib); 
+		Dakota::ParallelLibrary parallel_lib(dakotamode); //use our own ISSM Dakota library mode constructor, which only fires up Dakota on CPU 0.
+		Dakota::ProblemDescDB problem_db(parallel_lib);
 		xDelete<char>(dakotamode);
 
@@ -289,5 +289,5 @@
 		selected_strategy.run_strategy();
 
-		//Warn other cpus that we are done running the dakota iterator, by setting the counter to -1:
+		//Warn other CPUs that we are done running the Dakota iterator, by setting the counter to -1:
 		DakotaSpawnCore(NULL,0, NULL,NULL,0,femmodel,-1);
 
@@ -296,9 +296,9 @@
 
 		for(;;){
-			if(!DakotaSpawnCore(NULL,0, NULL,NULL,0,femmodel,0))break; //counter came in at -1 on cpu0, bail out.
+			if(!DakotaSpawnCore(NULL,0, NULL,NULL,0,femmodel,0)) break; //counter came in at -1 on CPU 0, bail out.
 		}
 	}
 
-	/*Free ressources:*/
+	/*Free resources:*/
 	xDelete<char>(dakota_input_file);
 	xDelete<char>(dakota_error_file);
@@ -307,6 +307,6 @@
 } /*}}}*/
 #else
-void dakota_core(FemModel* femmodel){ 
-	_error_("dakota_core for versions of Dakota >=6 should not be used anymore! Use instead the issm_dakota  executable!");
+void dakota_core(FemModel* femmodel){
+	_error_("dakota_core for versions of Dakota >=6 should not be used anymore! Use instead the issm_dakota executable!");
 }
 #endif
Index: /issm/trunk-jpl/src/c/modules/Scotchx/Scotchx.h
===================================================================
--- /issm/trunk-jpl/src/c/modules/Scotchx/Scotchx.h	(revision 24592)
+++ /issm/trunk-jpl/src/c/modules/Scotchx/Scotchx.h	(revision 24593)
@@ -1,10 +1,10 @@
 /*!\file:  Scotchxx.h
  * \brief header file for Scotch partitioner
- */ 
+ */
 
 #ifndef _SCOTCHX_H
 #define _SCOTCHX_H
 
-#undef __FUNCT__ 
+#undef __FUNCT__
 #define __FUNCT__  "Scotchx"
 
@@ -23,8 +23,15 @@
 	#define GMAP
 
-	#include "scotch_module.h"
-	#include "scotch_common.h"
-	#include "scotch.h"
-	#include "scotch_gmap.h"
+	#ifdef _PETSC_SCOTCH_
+		#include "scotch_module.h"
+		#include "scotch_common.h"
+		#include "scotch_gmap.h"
+	#endif
+
+	#ifdef _HAVE_MPI_
+		#include "ptscotch.h"
+	#else
+		#include "scotch.h"
+	#endif
 
 	/*
Index: /issm/trunk-jpl/src/c/shared/Numerics/constants.h
===================================================================
--- /issm/trunk-jpl/src/c/shared/Numerics/constants.h	(revision 24592)
+++ /issm/trunk-jpl/src/c/shared/Numerics/constants.h	(revision 24593)
@@ -1,5 +1,5 @@
 /*!\file: constants.h
  * \brief prototypes for constants.h
- */ 
+ */
 
 #ifndef _ISSM_CONSTANTS_H_
@@ -9,5 +9,5 @@
 #define SQRT2 1.414213562373095048801688724209698078569671875376948073176679738
 #define SQRT3 1.732050807568877293527446341505872366942805253810380628055806979
-#define PI 3.141592653589793238462643383279502884197169399375105820974944592308
+const double PI=3.141592653589793238462643383279502884197169399375105820974944592308; // Macro definition conflicts with Dakota's declaration of PI
 
 #define NDOF1 1
@@ -18,11 +18,11 @@
 // /*Windows specific typefefs: */
 // #ifdef _INTEL_WIN_
-// 
+//
 // #ifndef NAN
 // //For reference, for Intel compile on win64
-// //#define NAN 0.0/0.0 
+// //#define NAN 0.0/0.0
 // #define NAN (INFINITY-INFINITY)
 // #endif
-// 
+//
 // #ifndef INFINITY
 // //For reference, for Intel compile on win64
@@ -30,5 +30,5 @@
 // #define INFINITY (DBL_MAX+DBL_MAX)
 // #endif
-// 
+//
 // #endif /*_INTEL_WIN_*/
 
Index: /issm/trunk-jpl/src/c/toolkits/mpi/issmmpi.h
===================================================================
--- /issm/trunk-jpl/src/c/toolkits/mpi/issmmpi.h	(revision 24592)
+++ /issm/trunk-jpl/src/c/toolkits/mpi/issmmpi.h	(revision 24593)
@@ -1,4 +1,4 @@
 /* \file issmmpi.h
- * \brief: header file that defines all the mpi wrappers that ISSM requires. The goal is to control 
+ * \brief: header file that defines all the mpi wrappers that ISSM requires. The goal is to control
  * which MPI layer we are using at compile time: the standard mpi, the autodiff mpi or no mpi at all.
  */
@@ -39,7 +39,7 @@
 			#include <ampi/ampi.h>
 		#endif
-	#elif  _HAVE_PETSC_MPI_ // Petsc now hides there MPI header. It can be reached through Petsc.
+	#elif  _HAVE_PETSC_MPI_ // PETSc now hides their MPI header. It can be reached through PETSc's header file.
 		#include <petsc.h>
-	#else 
+	#else
 		#include <mpi.h>
 	#endif
@@ -66,5 +66,5 @@
 	#define ISSM_MPI_INT           AMPI_INT
 	#define ISSM_MPI_LONG_LONG_INT AMPI_LONG_LONG_INT
-	
+
 	// operations
 	#define ISSM_MPI_MAX        AMPI_MAX
@@ -72,5 +72,5 @@
 	#define ISSM_MPI_PROD       AMPI_PROD
 	#define ISSM_MPI_SUM        AMPI_SUM
-	
+
 	// others
 	#define ISSM_MPI_COMM_WORLD    AMPI_COMM_WORLD
@@ -82,5 +82,5 @@
 		#if defined(_HAVE_AMPI_) && !defined(_WRAPPERS_)
 			#define ISSM_MPI_DOUBLE    AMPI_ADOUBLE
-		#else 
+		#else
 			#define ISSM_MPI_DOUBLE    MPI_DOUBLE
 		#endif
@@ -106,5 +106,5 @@
 	#include "./commops/commops.h"
 	/*}}}*/
-#else  
+#else
 	/*Our ISSM MPI defines: {{{*/
 	// types
@@ -134,10 +134,10 @@
 	#define ISSM_MPI_ANY_SOURCE    3
 	/*}}}*/
-#endif 
+#endif
 
 /*Dynamically return ISSM_MPI type from variable type */
 template <class T> ISSM_MPI_Datatype TypeToMPIType(){assert(false);};
 template <> inline ISSM_MPI_Datatype TypeToMPIType<IssmDouble>(){return ISSM_MPI_DOUBLE;};
-#if defined(_HAVE_AD_) && !defined(_WRAPPERS_) 
+#if defined(_HAVE_AD_) && !defined(_WRAPPERS_)
 template <> inline ISSM_MPI_Datatype TypeToMPIType<IssmPDouble>(){return ISSM_MPI_PDOUBLE;};
 #endif
@@ -154,5 +154,5 @@
 #ifdef _HAVE_MPI_
 # ifdef _HAVE_AMPI_
-	rc=AMPI_Bcast(buffer, 
+	rc=AMPI_Bcast(buffer,
 				count,
 				datatype,
@@ -160,5 +160,5 @@
 				comm);
 # else
-	rc=MPI_Bcast(buffer, 
+	rc=MPI_Bcast(buffer,
 				count,
 				datatype,
@@ -166,6 +166,6 @@
 				comm);
 # endif
-#else 
-	// nothing to be done here 
+#else
+	// nothing to be done here
 #endif
 	return rc;
@@ -173,6 +173,6 @@
 /* interfaces  {{{*/
 int ISSM_MPI_Allgather(void *sendbuf, int sendcount, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcount, ISSM_MPI_Datatype recvtype, ISSM_MPI_Comm comm);
-int ISSM_MPI_Allgatherv(void *sendbuf, int sendcount, ISSM_MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs, ISSM_MPI_Datatype recvtype, ISSM_MPI_Comm comm); 
-int ISSM_MPI_Allreduce(void *sendbuf, void *recvbuf, int count, ISSM_MPI_Datatype datatype, ISSM_MPI_Op op, ISSM_MPI_Comm comm); 
+int ISSM_MPI_Allgatherv(void *sendbuf, int sendcount, ISSM_MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs, ISSM_MPI_Datatype recvtype, ISSM_MPI_Comm comm);
+int ISSM_MPI_Allreduce(void *sendbuf, void *recvbuf, int count, ISSM_MPI_Datatype datatype, ISSM_MPI_Op op, ISSM_MPI_Comm comm);
 int ISSM_MPI_Barrier(ISSM_MPI_Comm comm);
 int ISSM_MPI_Bcast(void *buffer, int count, ISSM_MPI_Datatype datatype, int root, ISSM_MPI_Comm comm);
@@ -186,6 +186,6 @@
 int ISSM_MPI_Recv(void *buf, int count, ISSM_MPI_Datatype datatype, int source, int tag, ISSM_MPI_Comm comm, ISSM_MPI_Status *status);
 int ISSM_MPI_Reduce(void *sendbuf, void *recvbuf, int count, ISSM_MPI_Datatype datatype, ISSM_MPI_Op op, int root, ISSM_MPI_Comm comm);
-int ISSM_MPI_Scatter(void *sendbuf, int sendcnt, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcnt, ISSM_MPI_Datatype recvtype, int root, ISSM_MPI_Comm comm); 
-int ISSM_MPI_Scatterv(void *sendbuf, int *sendcnts, int *displs, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcnt, ISSM_MPI_Datatype recvtype, int root, ISSM_MPI_Comm comm); 
+int ISSM_MPI_Scatter(void *sendbuf, int sendcnt, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcnt, ISSM_MPI_Datatype recvtype, int root, ISSM_MPI_Comm comm);
+int ISSM_MPI_Scatterv(void *sendbuf, int *sendcnts, int *displs, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcnt, ISSM_MPI_Datatype recvtype, int root, ISSM_MPI_Comm comm);
 int ISSM_MPI_Send(void *buf, int count, ISSM_MPI_Datatype datatype, int dest, int tag, ISSM_MPI_Comm comm);
 double ISSM_MPI_Wtime(void);
@@ -194,5 +194,5 @@
 
 // special for Adol-C locations when buffers are allocated with new
-// this could end up in the xNew template specialized for adoubles 
+// this could end up in the xNew template specialized for adoubles
 // so as to not litter the code with it.
 void ISSM_MPI_ContiguousInAdolc(size_t aSize);
Index: /issm/trunk-jpl/src/m/Makefile.am
===================================================================
--- /issm/trunk-jpl/src/m/Makefile.am	(revision 24592)
+++ /issm/trunk-jpl/src/m/Makefile.am	(revision 24593)
@@ -3,77 +3,94 @@
 #find . -type d -exec ls -d {} \;
 
-bin_SCRIPTS = 
+bin_SCRIPTS =
 if WRAPPERS
 if MATLAB
 if !DEVELOPMENT
-bin_SCRIPTS += ${ISSM_DIR}/src/m/qmu/*.m \
-					${ISSM_DIR}/src/m/archive/*.m \
-					${ISSM_DIR}/src/m/qmu/setupdesign/*.m \
-					${ISSM_DIR}/src/m/qmu/plot/*.m \
-					${ISSM_DIR}/src/m/qmu/examples/*.m \
-					${ISSM_DIR}/src/m/kml/*.m \
-					${ISSM_DIR}/src/m/dev/issmversion.m \
-					${ISSM_DIR}/src/m/classes/*.m \
-					${ISSM_DIR}/src/m/classes/qmu/*.m \
-					${ISSM_DIR}/src/m/classes/qmu/dakota_method/*.m \
-					${ISSM_DIR}/src/m/classes/clusters/*.m \
-					${ISSM_DIR}/src/m/consistency/*.m \
-					${ISSM_DIR}/src/m/array/*.m \
-					${ISSM_DIR}/src/m/boundaryconditions/*.m \
-					${ISSM_DIR}/src/m/exp/*.m \
-					${ISSM_DIR}/src/m/exp/operation/*.m \
-					${ISSM_DIR}/src/m/geometry/*.m \
-					${ISSM_DIR}/src/m/interp/*.m \
-					${ISSM_DIR}/src/m/coordsystems/*.m \
-					${ISSM_DIR}/src/m/mech/*.m \
-					${ISSM_DIR}/src/m/mesh/*.m \
-					${ISSM_DIR}/src/m/mesh/planet/spheretri/*.m \
-					${ISSM_DIR}/src/m/mesh/planet/gmsh/*.m \
-					${ISSM_DIR}/src/m/mesh/rifts/*.m \
-					${ISSM_DIR}/src/m/miscellaneous/*.m \
-					${ISSM_DIR}/src/m/modules/*.m \
-					${ISSM_DIR}/src/m/os/*.m \
-					${ISSM_DIR}/src/m/plot/*.m \
-					${ISSM_DIR}/src/m/plot/colormaps/*.m \
-					${ISSM_DIR}/src/m/string/*.m \
-					${ISSM_DIR}/src/m/extrusion/*.m \
-					${ISSM_DIR}/src/m/inversions/*.m \
-					${ISSM_DIR}/src/m/io/*.m \
-					${ISSM_DIR}/src/m/parameterization/*.m \
-					${ISSM_DIR}/src/m/partition/*.m \
-					${ISSM_DIR}/src/m/print/*.m \
-					${ISSM_DIR}/src/m/regional/*.m \
-					${ISSM_DIR}/src/m/solve/*.m \
-					${ISSM_DIR}/src/m/solvers/*.m \
-					${ISSM_DIR}/src/m/materials/*.m
+# TODO: There should be a better way of doing this so that manual updating is
+#		not required when a new subdirectory or module is introduced (search
+#		all subdirectories for file type, checking against an exclude list)
+bin_SCRIPTS += \
+	${ISSM_DIR}/src/m/archive/*.m \
+	${ISSM_DIR}/src/m/array/*.m \
+	${ISSM_DIR}/src/m/boundaryconditions/*.m \
+	${ISSM_DIR}/src/m/classes/*.m \
+	${ISSM_DIR}/src/m/classes/clusters/*.m \
+	${ISSM_DIR}/src/m/classes/qmu/*.m \
+	${ISSM_DIR}/src/m/classes/qmu/dakota_method/*.m \
+	${ISSM_DIR}/src/m/consistency/*.m \
+	${ISSM_DIR}/src/m/coordsystems/*.m \
+	${ISSM_DIR}/src/m/dev/issmversion.m \
+	${ISSM_DIR}/src/m/exp/*.m \
+	${ISSM_DIR}/src/m/exp/operation/*.m \
+	${ISSM_DIR}/src/m/extrusion/*.m \
+	${ISSM_DIR}/src/m/geometry/*.m \
+	${ISSM_DIR}/src/m/interp/*.m \
+	${ISSM_DIR}/src/m/inversions/*.m \
+	${ISSM_DIR}/src/m/io/*.m \
+	${ISSM_DIR}/src/m/kml/*.m \
+	${ISSM_DIR}/src/m/materials/*.m \
+	${ISSM_DIR}/src/m/mech/*.m \
+	${ISSM_DIR}/src/m/mesh/*.m \
+	${ISSM_DIR}/src/m/mesh/planet/gmsh/*.m \
+	${ISSM_DIR}/src/m/mesh/planet/spheretri/*.m \
+	${ISSM_DIR}/src/m/mesh/rifts/*.m \
+	${ISSM_DIR}/src/m/miscellaneous/*.m \
+	${ISSM_DIR}/src/m/modules/*.m \
+	${ISSM_DIR}/src/m/os/*.m \
+	${ISSM_DIR}/src/m/parameterization/*.m \
+	${ISSM_DIR}/src/m/partition/*.m \
+	${ISSM_DIR}/src/m/plot/*.m \
+	${ISSM_DIR}/src/m/plot/colormaps/*.m \
+	${ISSM_DIR}/src/m/print/*.m \
+	${ISSM_DIR}/src/m/qmu/*.m \
+	${ISSM_DIR}/src/m/qmu/examples/*.m \
+	${ISSM_DIR}/src/m/qmu/plot/*.m \
+	${ISSM_DIR}/src/m/qmu/setupdesign/*.m \
+	${ISSM_DIR}/src/m/regional/*.m \
+	${ISSM_DIR}/src/m/solve/*.m \
+	${ISSM_DIR}/src/m/solvers/*.m \
+	${ISSM_DIR}/src/m/string/*.m
 endif
 endif
+
 if PYTHON
 if !DEVELOPMENT
-bin_SCRIPTS += ${ISSM_DIR}/src/m/archive/*.py \
-					${ISSM_DIR}/src/m/classes/*.py \
-					${ISSM_DIR}/src/m/classes/clusters/*.py \
-					${ISSM_DIR}/src/m/consistency/*.py \
-					${ISSM_DIR}/src/m/dev/issmversion.py \
-					${ISSM_DIR}/src/m/boundaryconditions/*.py \
-					${ISSM_DIR}/src/m/exp/*.py \
-					${ISSM_DIR}/src/m/geometry/*.py \
-					${ISSM_DIR}/src/m/coordsystems/*.py \
-					${ISSM_DIR}/src/m/interp/*.py \
-					${ISSM_DIR}/src/m/inversions/*.py \
-					${ISSM_DIR}/src/m/mech/*.py \
-					${ISSM_DIR}/src/m/mesh/*.py \
-					${ISSM_DIR}/src/m/mesh/rifts/*.py \
-					${ISSM_DIR}/src/m/mesh/planet/gmsh/*.py \
-					${ISSM_DIR}/src/m/miscellaneous/*.py \
-					${ISSM_DIR}/src/m/modules/*.py \
-					${ISSM_DIR}/src/m/os/*.py \
-					${ISSM_DIR}/src/m/plot/*.py \
-					${ISSM_DIR}/src/m/extrusion/*.py \
-					${ISSM_DIR}/src/m/io/*.py \
-					${ISSM_DIR}/src/m/parameterization/*.py \
-					${ISSM_DIR}/src/m/solve/*.py \
-					${ISSM_DIR}/src/m/solvers/*.py \
-					${ISSM_DIR}/src/m/materials/*.py
+# TODO: There should be a better way of doing this so that manual updating is
+#		not required when a new subdirectory or module is introduced (search
+#		all subdirectories for file type, checking against an exclude list)
+bin_SCRIPTS += \
+	${ISSM_DIR}/src/m/archive/*.py \
+	${ISSM_DIR}/src/m/array/*.py \
+	${ISSM_DIR}/src/m/boundaryconditions/*.py \
+	${ISSM_DIR}/src/m/classes/*.py \
+	${ISSM_DIR}/src/m/classes/clusters/*.py \
+	${ISSM_DIR}/src/m/classes/qmu/*.py \
+	${ISSM_DIR}/src/m/classes/qmu/dakota_method/*.py \
+	${ISSM_DIR}/src/m/consistency/*.py \
+	${ISSM_DIR}/src/m/coordsystems/*.py \
+	${ISSM_DIR}/src/m/dev/issmversion.py \
+	${ISSM_DIR}/src/m/exp/*.py \
+	${ISSM_DIR}/src/m/extrusion/*.py \
+	${ISSM_DIR}/src/m/geometry/*.py \
+	${ISSM_DIR}/src/m/interp/*.py \
+	${ISSM_DIR}/src/m/inversions/*.py \
+	${ISSM_DIR}/src/m/io/*.py \
+	${ISSM_DIR}/src/m/materials/*.py \
+	${ISSM_DIR}/src/m/mech/*.py \
+	${ISSM_DIR}/src/m/mesh/*.py \
+	${ISSM_DIR}/src/m/mesh/planet/gmsh/*.py \
+	${ISSM_DIR}/src/m/mesh/rifts/*.py \
+	${ISSM_DIR}/src/m/miscellaneous/*.py \
+	${ISSM_DIR}/src/m/modules/*.py \
+	${ISSM_DIR}/src/m/os/*.py \
+	${ISSM_DIR}/src/m/parameterization/*.py \
+	${ISSM_DIR}/src/m/partition/*.py \
+	${ISSM_DIR}/src/m/plot/*.py \
+	${ISSM_DIR}/src/m/plot/colormaps/*.py \
+	${ISSM_DIR}/src/m/qmu/*.py \
+	${ISSM_DIR}/src/m/qmu/setupdesign/*.py \
+	${ISSM_DIR}/src/m/shp/*.py \
+	${ISSM_DIR}/src/m/solve/*.py \
+	${ISSM_DIR}/src/m/solvers/*.py
 endif
 endif
@@ -81,24 +98,27 @@
 if JAVASCRIPT
 if !DEVELOPMENT
-
-js_scripts = ${ISSM_DIR}/src/m/array/*.js \
-				${ISSM_DIR}/src/m/boundaryconditions/*.js \
-				${ISSM_DIR}/src/m/classes/*.js \
-                ${ISSM_DIR}/src/m/classes/clusters/*.js \
-				${ISSM_DIR}/src/m/consistency/*.js \
-				${ISSM_DIR}/src/m/exp/*.js \
-				${ISSM_DIR}/src/m/extrusion/*.js \
-				${ISSM_DIR}/src/m/geometry/*.js \
-				${ISSM_DIR}/src/m/inversions/*.js \
-				${ISSM_DIR}/src/m/io/*.js \
-				${ISSM_DIR}/src/m/materials/*.js \
-				${ISSM_DIR}/src/m/mesh/*.js \
-				${ISSM_DIR}/src/m/miscellaneous/*.js \
-				${ISSM_DIR}/src/m/parameterization/*.js \
-				${ISSM_DIR}/src/m/plot/*.js \
-				${ISSM_DIR}/src/m/print/*.js \
-				${ISSM_DIR}/src/m/shp/*.js \
-				${ISSM_DIR}/src/m/solve/*.js \
-				${ISSM_DIR}/src/m/solvers/*.js
+# TODO: There should be a better way of doing this so that manual updating is
+#		not required when a new subdirectory or module is introduced (search
+#		all subdirectories for file type, checking against an exclude list)
+js_scripts = \
+	${ISSM_DIR}/src/m/array/*.js \
+	${ISSM_DIR}/src/m/boundaryconditions/*.js \
+	${ISSM_DIR}/src/m/classes/*.js \
+	${ISSM_DIR}/src/m/classes/clusters/*.js \
+	${ISSM_DIR}/src/m/consistency/*.js \
+	${ISSM_DIR}/src/m/exp/*.js \
+	${ISSM_DIR}/src/m/extrusion/*.js \
+	${ISSM_DIR}/src/m/geometry/*.js \
+	${ISSM_DIR}/src/m/inversions/*.js \
+	${ISSM_DIR}/src/m/io/*.js \
+	${ISSM_DIR}/src/m/materials/*.js \
+	${ISSM_DIR}/src/m/mesh/*.js \
+	${ISSM_DIR}/src/m/miscellaneous/*.js \
+	${ISSM_DIR}/src/m/parameterization/*.js \
+	${ISSM_DIR}/src/m/plot/*.js \
+	${ISSM_DIR}/src/m/print/*.js \
+	${ISSM_DIR}/src/m/shp/*.js \
+	${ISSM_DIR}/src/m/solve/*.js \
+	${ISSM_DIR}/src/m/solvers/*.js
 bin_SCRIPTS +=  issm-bin.js
 
Index: /issm/trunk-jpl/src/m/classes/clusters/generic.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic.m	(revision 24592)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic.m	(revision 24593)
@@ -6,5 +6,5 @@
 
 classdef generic
-	properties (SetAccess=public) 
+	properties (SetAccess=public)
 		% {{{
 		name          = '';
@@ -75,10 +75,10 @@
 		%}}}
 		function BuildQueueScript(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota,isoceancoupling) % {{{
-
-			%write queuing script 
-			%what is the executable being called? 
-			executable='issm.exe';
+			% Which executable are we calling?
+			executable='issm.exe'; % default
+
 			if isdakota,
-				version=IssmConfig('_DAKOTA_VERSION_'); version=str2num(version(1:3));
+				version=IssmConfig('_DAKOTA_VERSION_');
+				version=str2num(version(1:3));
 				if (version>=6),
 					executable='issm_dakota.exe';
@@ -90,5 +90,4 @@
 
 			if ~ispc(),
-
 				fid=fopen([modelname '.queue'],'w');
 				fprintf(fid,'#!%s\n',cluster.shell);
@@ -112,5 +111,5 @@
 					%Add --gen-suppressions=all to get suppression lines
 					%fprintf(fid,'LD_PRELOAD=%s \\\n',cluster.valgrindlib); it could be deleted
-					if ismac, 
+					if ismac,
 						if IssmConfig('_HAVE_MPI_'),
 							fprintf(fid,'mpiexec -np %i %s --leak-check=full --error-limit=no --dsymutil=yes --suppressions=%s %s/%s %s %s %s 2> %s.errlog >%s.outlog ',...
@@ -161,33 +160,33 @@
 		%}}}
 		function BuildQueueScriptMultipleModels(cluster,dirname,modelname,solution,dirnames,modelnames,nps) % {{{
-		
-			%some checks: 
+
+			%some checks:
 			if isempty(modelname), error('BuildQueueScriptMultipleModels error message: need a non empty model name!');end
 
-			%what is the executable being called? 
+			%what is the executable being called?
 			executable='issm_slr.exe';
 
 			if ispc(), error('BuildQueueScriptMultipleModels not support yet on windows machines');end;
-			
-			%write queuing script 
+
+			%write queuing script
 			fid=fopen([modelname '.queue'],'w');
-			
+
 			fprintf(fid,'#!%s\n',cluster.shell);
 
-			%number of cpus: 
+			%number of cpus:
 			mpistring=sprintf('mpiexec -np %i ',cluster.np);
 
-			%executable: 
+			%executable:
 			mpistring=[mpistring sprintf('%s/%s ',cluster.codepath,executable)];
-			
-			%solution name: 
+
+			%solution name:
 			mpistring=[mpistring sprintf('%s ',solution)];
 
-			%execution directory and model name: 
+			%execution directory and model name:
 			mpistring=[mpistring sprintf('%s/%s %s',cluster.executionpath,dirname,modelname)];
 
-			%inform main executable of how many icecaps, glaciers and earth models are being run: 
+			%inform main executable of how many icecaps, glaciers and earth models are being run:
 			mpistring=[mpistring sprintf(' %i ',length(dirnames))];
-			
+
 			%icecaps, glaciers and earth location, names and number of processors associated:
 			for i=1:length(dirnames),
@@ -195,10 +194,10 @@
 			end
 
-			%log files: 
+			%log files:
 			if ~cluster.interactive,
 				mpistring=[mpistring sprintf('2> %s.errlog> %s.outlog',modelname,modelname)];
 			end
 
-			%write this long string to disk: 
+			%write this long string to disk:
 			fprintf(fid,mpistring);
 			fclose(fid);
@@ -213,6 +212,6 @@
 		function BuildQueueScriptIceOcean(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota) % {{{
 
-			%write queuing script 
-			%what is the executable being called? 
+			%write queuing script
+			%what is the executable being called?
 			executable='issm_ocean.exe';
 
@@ -237,5 +236,5 @@
 		function BuildKrigingQueueScript(cluster,modelname,solution,io_gather,isvalgrind,isgprof) % {{{
 
-			%write queuing script 
+			%write queuing script
 			if ~ispc(),
 
Index: /issm/trunk-jpl/src/m/classes/clusters/generic.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic.py	(revision 24592)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic.py	(revision 24593)
@@ -32,4 +32,6 @@
         self.valgrindlib = '/usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so.20.10.1'
         self.valgrindsup = [issmdir() + '/externalpackages/valgrind/issm.supp']  # add any .supp in list form as needed
+        self.verbose = 1
+        self.shell = '/bin/sh'
 
         #use provided options to change fields
@@ -63,4 +65,6 @@
         s += "    valgrindlib: %s\n" % self.valgrindlib
         s += "    valgrindsup: %s\n" % self.valgrindsup
+        s += "    verbose: %s\n" % self.verbose
+        s += "    shell: %s\n" % self.shell
         return s
     # }}}
@@ -74,6 +78,7 @@
     # }}}
     def BuildQueueScript(self, dirname, modelname, solution, io_gather, isvalgrind, isgprof, isdakota, isoceancoupling):  # {{{
-
-        executable = 'issm.exe'
+        # Which executable are we calling?
+        executable = 'issm.exe' # default
+
         if isdakota:
             version = IssmConfig('_DAKOTA_VERSION_')
@@ -84,5 +89,5 @@
             executable = 'issm_ocean.exe'
 
-        #write queuing script
+        # Write queueing script
         if not m.ispc():
             fid = open(modelname + '.queue', 'w')
@@ -191,10 +196,10 @@
         print('launching solution sequence on remote cluster')
         if restart:
-            launchcommand = 'cd {} && cd {} chmod 777 {}.queue && ./{}.queue'.format(self.executionpath, dirname, modelname, modelname)
+            launchcommand = 'cd {} && cd {} chmod 755 {}.queue && ./{}.queue'.format(self.executionpath, dirname, modelname, modelname)
         else:
             if batch:
                 launchcommand = 'cd {} && rm -rf ./{} && mkdir {} && cd {} && mv ../{}.tar.gz ./&& tar -zxf {}.tar.gz'.format(self.executionpath, dirname, dirname, dirname, dirname, dirname)
             else:
-                launchcommand = 'cd {} && rm -rf ./{} && mkdir {} && cd {} && mv ../{}.tar.gz ./&& tar -zxf {}.tar.gz  && chmod 777 {}.queue && ./{}.queue'.format(self.executionpath, dirname, dirname, dirname, dirname, dirname, modelname, modelname)
+                launchcommand = 'cd {} && rm -rf ./{} && mkdir {} && cd {} && mv ../{}.tar.gz ./&& tar -zxf {}.tar.gz  && chmod 755 {}.queue && ./{}.queue'.format(self.executionpath, dirname, dirname, dirname, dirname, dirname, modelname, modelname)
         issmssh(self.name, self.login, self.port, launchcommand)
     # }}}
Index: /issm/trunk-jpl/src/m/classes/clusters/generic_static.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic_static.m	(revision 24592)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic_static.m	(revision 24593)
@@ -5,11 +5,11 @@
 
 classdef generic_static
-	properties (SetAccess=public) 
+	properties (SetAccess=public)
 		% {{{
 		name='';
 		np=1;
 		codepath=fileparts(which('issm.exe'));
-		executionpath = '.';
-		interactive = 1;
+		executionpath='.';
+		interactive=1;
 		shell='/bin/sh';
 		%}}}
@@ -17,5 +17,4 @@
 	methods
 		function cluster=generic_static(varargin) % {{{
-
 			%use provided options to change fields
 			options=pairoptions(varargin{:});
@@ -50,18 +49,10 @@
 		%}}}
 		function BuildQueueScript(cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota,isoceancoupling) % {{{
+			% Which executable are we calling?
+			executable='issm.exe'; % default
 
-			%Check that issm.exe exists in the right path
-			if ~exist([cluster.codepath '/issm.exe'],'file'),
-				error(['File ' cluster.codepath '/issm.exe does not exist']);
-			end
-
-			%Now process codepath and replace empty spaces with \ to avoid errors in queuing script
-			codepath2=strrep(cluster.codepath,' ','\ ');
-
-			%write queuing script
-			%what is the executable being called?
-			executable='issm.exe';
 			if isdakota,
-				version=IssmConfig('_DAKOTA_VERSION_'); version=str2num(version(1:3));
+				version=IssmConfig('_DAKOTA_VERSION_');
+				version=str2num(version(1:3));
 				if (version>=6),
 					executable='issm_dakota.exe';
@@ -72,24 +63,32 @@
 			end
 
-			%write queuing script 
+			% Check that executable exists at the right path
+			if ~exist([cluster.codepath '/' executable],'file'),
+				error(['File ' cluster.codepath '/' executable ' does not exist']);
+			end
+
+			% Process codepath and prepend empty spaces with \ to avoid errors in queuing script
+			codepath=strrep(cluster.codepath,' ','\ ');
+
+			% Write queueing script
 			fid=fopen([modelname '.queue'],'w');
 			fprintf(fid,'#!%s\n',cluster.shell);
-			fprintf(fid,['%s/mpiexec -np %i %s/%s %s %s %s \n'],codepath2,cluster.np,codepath2,executable,solution,'./',modelname);
+			fprintf(fid,['%s/mpiexec -np %i %s/%s %s %s %s \n'],codepath,cluster.np,codepath,executable,solution,'./',modelname);
 			fclose(fid);
 
-			%in interactive mode, create a run file, and errlog and outlog file
-			fid=fopen([modelname '.errlog'],'w'); fclose(fid);
-			fid=fopen([modelname '.outlog'],'w'); fclose(fid);
+			% Create an errlog and outlog file
+			fid=fopen([modelname '.errlog'],'w');
+			fclose(fid);
+			fid=fopen([modelname '.outlog'],'w');
+			fclose(fid);
 		end
 		%}}}
 		function UploadQueueJob(cluster,modelname,dirname,filelist)% {{{
-
-			%do nothing
+			% Do nothing
+			return;
 		end %}}}
 		function LaunchQueueJob(cluster,modelname,dirname,filelist,restart,batch)% {{{
-
 			if ~ispc,
-
-				%figure out what shell extension we will use:
+				% Figure out which file extension to use
 				if isempty(strfind(cluster.shell,'csh')),
 					shellext='sh';
@@ -106,6 +105,6 @@
 		end %}}}
 		function Download(cluster,dirname,filelist)% {{{
-				%do nothing
-				return;
+			% Do nothing
+			return;
 		end %}}}
 	end
Index: /issm/trunk-jpl/src/m/classes/clusters/generic_static.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/clusters/generic_static.py	(revision 24593)
+++ /issm/trunk-jpl/src/m/classes/clusters/generic_static.py	(revision 24593)
@@ -0,0 +1,159 @@
+import socket
+import os
+import math
+import subprocess
+from IssmConfig import IssmConfig
+from issmdir import issmdir
+from pairoptions import pairoptions
+from issmssh import issmssh
+from issmscpin import issmscpin
+from issmscpout import issmscpout
+import MatlabFuncs as m
+
+
+class generic_static(object):
+    """
+    GENERIC cluster class definition
+
+       Usage:
+          cluster = generic_static('name', 'astrid', 'np', 3)
+    """
+
+    def __init__(self, *args):  # {{{
+        codepath = subprocess.check_output(["which", "issm.exe"]).rstrip('\r\n')
+        codepath = codepath.replace('/issm.exe', '')
+
+        self.name = ''
+        self.np = 1
+        self.codepath = codepath
+        self.executionpath = '.'
+        self.interactive = 1
+        self.shell = '/bin/sh'
+
+        #use provided options to change fields
+        options = pairoptions(*args)
+
+        #get name
+        self.name = socket.gethostname()
+
+        #initialize cluster using user settings if provided
+        if os.path.exists(self.name + '_settings.py'):
+            exec(compile(open(self.name + '_settings.py').read(), self.name + '_settings.py', 'exec'), globals())
+
+        #OK get other fields
+        self = options.AssignObjectFields(self)
+    # }}}
+
+    def __repr__(self):  # {{{
+        #  display the object
+        s = "class '%s' object '%s' = \n" % (type(self), 'self')
+        s += "    name: %s\n" % self.name
+        s += "    np: %i\n" % self.np
+        s += "    codepath: %s\n" % self.codepath
+        s += "    shell: %s\n" % self.shell
+        return s
+    # }}}
+
+    def checkconsistency(self, md, solution, analyses):  # {{{
+        if self.np < 1:
+            md = checkmessage(md, 'number of processors should be at least 1')
+        if math.isnan(self.np):
+            md = checkmessage(md, 'number of processors should not be NaN!')
+
+        return md
+    # }}}
+    def BuildQueueScript(self, dirname, modelname, solution, io_gather, isvalgrind, isgprof, isdakota, isoceancoupling):  # {{{
+        # Which executable are we calling?
+        executable = 'issm.exe' # default
+
+        if isdakota:
+            version = IssmConfig('_DAKOTA_VERSION_')
+            version = float(version[0])
+            if version >= 6:
+                executable = 'issm_dakota.exe'
+        if isoceancoupling:
+            executable = 'issm_ocean.exe'
+
+        # Check that executable exists at the right path
+        if not os.path.isfile(self.codepath + '/' + executable):
+            raise RuntimeError('File ' + self.codepath + '/' + executable + ' does not exist')
+
+        # Process codepath and prepend empty spaces with \ to avoid errors in queuing script
+        codepath = self.codepath.replace(' ', '\ ')
+
+        # Write queueing script
+        fid = open(modelname + '.queue', 'w')
+        fid.write('#!{}'.format(self.shell) + '\n')
+        fid.write('{}/mpiexec -np {} {}/{} {} {} {}'.format(codepath, self.np, codepath, executable, solution, './', modelname))
+        fid.close()
+
+        # Set permissions on queue script so that it can be run
+        subprocess.call(['chmod', '0755', modelname + '.queue'])
+
+        # Create an errlog and outlog file
+        fid = open(modelname + '.errlog', 'w')
+        fid.close()
+        fid = open(modelname + '.outlog', 'w')
+        fid.close()
+    # }}}
+
+    def BuildKrigingQueueScript(self, modelname, solution, io_gather, isvalgrind, isgprof):  # {{{
+        # Which executable are we calling?
+        executable = 'kriging.exe' # default
+
+        if isdakota:
+            version = IssmConfig('_DAKOTA_VERSION_')
+            version = float(version[0])
+            if version >= 6:
+                executable = 'issm_dakota.exe'
+        if isoceancoupling:
+            executable = 'issm_ocean.exe'
+
+        # Check that executable exists at the right path
+        if not os.path.isfile(self.codepath + '/' + executable):
+            raise RuntimeError('File ' + self.codepath + '/' + executable + ' does not exist')
+
+        # Process codepath and prepend empty spaces with \ to avoid errors in queuing script
+        codepath = self.codepath.replace(' ', '\ ')
+
+        # Write queueing script
+        fid = open(modelname + '.queue', 'w')
+        fid.write('#!{}'.format(self.shell) + '\n')
+        fid.write('{}/mpiexec -np {} {}/{} {} {} {}'.format(codepath, self.np, codepath, executable, solution, './', modelname) + '\n')
+        fid.close()
+
+        # Set permissions on queue script so that it can be run
+        subprocess.call(['chmod', '0755', modelname + '.queue'])
+
+        # Create an errlog and outlog file
+        fid = open(modelname + '.errlog', 'w')
+        fid.close()
+        fid = open(modelname + '.outlog', 'w')
+        fid.close()
+    # }}}
+
+    def UploadQueueJob(self, modelname, dirname, filelist):  # {{{
+        # Do nothing
+        return
+    # }}}
+
+    def LaunchQueueJob(self, modelname, dirname, filelist, restart, batch):  # {{{
+        if not m.ispc():
+            # Figure out which file extension to use
+            if self.shell.find('csh') == -1:
+                shellext='sh'
+            else:
+                shellext='csh'
+
+            print('launching solution sequence')
+            launchcommand = './' + modelname + '.queue'
+            subprocess.call([launchcommand])
+        else:
+            launchcommand = './' + modelname + '.bat'
+            subprocess.call([launchcommand])
+    # }}}
+
+    def Download(self, dirname, filelist):  # {{{
+        # Do nothing
+        return
+    # }}}
Index: /issm/trunk-jpl/src/m/classes/model.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/model.py	(revision 24592)
+++ /issm/trunk-jpl/src/m/classes/model.py	(revision 24593)
@@ -144,5 +144,5 @@
                 'initialization',
                 'rifts',
-                'slr', 
+                'slr',
                 'dsl',
                 'debug',
@@ -811,8 +811,11 @@
         md.stressbalance.referential = project2d(md, md.stressbalance.referential, md.mesh.numberoflayers)
         md.stressbalance.loadingforce = project2d(md, md.stressbalance.loadingforce, md.mesh.numberoflayers)
-        md.masstransport.spcthickness = project2d(md, md.masstransport.spcthickness, md.mesh.numberoflayers)
+        if np.size(md.masstransport.spcthickness) > 1:
+            md.masstransport.spcthickness = project2d(md, md.masstransport.spcthickness, md.mesh.numberoflayers)
+        if np.size(md.damage.spcdamage) > 1 and not np.isnan(md.damage.spcdamage).all():
+            md.damage.spcdamage = project2d(md, md.damage.spcdamage, md.mesh.numberoflayers - 1)
+        if np.size(md.levelset.spclevelset) > 1:
+            md.levelset.spclevelset = project2d(md, md.levelset.spclevelset, md.mesh.numberoflayers - 1)
         md.thermal.spctemperature = project2d(md, md.thermal.spctemperature, md.mesh.numberoflayers - 1)
-        if not np.isnan(md.damage.spcdamage).all():
-            md.damage.spcdamage = project2d(md, md.damage.spcdamage, md.mesh.numberoflayers - 1)
 
         #materials
Index: /issm/trunk-jpl/src/m/classes/qmu.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/qmu.m	(revision 24592)
+++ /issm/trunk-jpl/src/m/classes/qmu.m	(revision 24593)
@@ -5,5 +5,5 @@
 
 classdef qmu
-	properties (SetAccess=public) 
+	properties (SetAccess=public)
 		isdakota                    = 0;
 		output                      = 0;
@@ -87,16 +87,16 @@
 				end
 				if md.cluster.np<=1,
-					md = checkmessage(md,['in parallel library mode, Dakota needs to run on at least 2 cpus, 1 cpu for the master, 1 cpu for the slave. Modify md.cluser.np accordingly.']);
-				end
-					
+					md = checkmessage(md,['in parallel library mode, Dakota needs to run on at least 2 cpus, 1 cpu for the master, 1 cpu for the slave. Modify md.cluster.np accordingly.']);
+				end
+
 				if self.params.processors_per_evaluation<1,
 					md = checkmessage(md,['in parallel library mode, Dakota needs to run at least one slave on one cpu (md.qmu.params.processors_per_evaluation >=1)!']);
 				end
-				if mod(md.cluster.np-1,self.params.processors_per_evaluation), 
+				if mod(md.cluster.np-1,self.params.processors_per_evaluation),
 					%md = checkmessage(md,['in parallel library mode, the requirement is for md.cluster.np = md.qmu.params.processors_per_evaluation * number_of_slaves, where number_of_slaves will automatically be determined by Dakota. Modify md.cluster.np accordingly']);
 				end
 			end
 			if ~isempty(md.qmu.vpartition) & ~any(isnan(md.qmu.vpartition)),
-				if size(md.qmu.vpartition,1)~=md.mesh.numberofvertices  
+				if size(md.qmu.vpartition,1)~=md.mesh.numberofvertices
 					md = checkmessage(md,['user supplied vertex partition for qmu analysis should have size md.mesh.numberofvertices x 1']);
 				end
@@ -109,5 +109,5 @@
 			end
 			if ~isempty(md.qmu.epartition) & ~any(isnan(md.qmu.epartition)),
-				if size(md.qmu.epartition,1)~=md.mesh.numberofelements, 
+				if size(md.qmu.epartition,1)~=md.mesh.numberofelements,
 					md = checkmessage(md,['user supplied element partition for qmu analysis should have size md.mesh.numberofelements x 1']);
 				end
@@ -157,5 +157,5 @@
 				end
 			end
-			fielddisplay(self,'numberofresponses','number of responses') 
+			fielddisplay(self,'numberofresponses','number of responses')
 			for i=1:numel(self.method);
 				if strcmp(class(self.method(i)),'dakota_method')
@@ -194,5 +194,5 @@
 			fielddisplay(self,'vpartition','user provided mesh partitioning (vertex based)');
 			fielddisplay(self,'epartition','user provided mesh partitioning (element based)');
-			fielddisplay(self,'numberofpartitions','number of partitions for semi-discrete qmu') 
+			fielddisplay(self,'numberofpartitions','number of partitions for semi-discrete qmu')
 			fielddisplay(self,'variabledescriptors','');
 			fielddisplay(self,'responsedescriptors','');
@@ -208,7 +208,7 @@
 			WriteData(fid,prefix,'object',self,'fieldname','isdakota','format','Boolean');
 			WriteData(fid,prefix,'object',self,'fieldname','output','format','Boolean');
-			if ~self.isdakota, 
+			if ~self.isdakota,
 				WriteData(fid,prefix,'data',false,'name','md.qmu.mass_flux_segments_present','format','Boolean');
-				return; 
+				return;
 			end
 			WriteData(fid,prefix,'object',self,'fieldname','vpartition','format','DoubleMat','mattype',2);
@@ -218,14 +218,14 @@
 			WriteData(fid,prefix,'object',self,'fieldname','variabledescriptors','format','StringArray');
 			WriteData(fid,prefix,'object',self,'fieldname','responsedescriptors','format','StringArray');
-			if ~isempty(self.mass_flux_segments), 
+			if ~isempty(self.mass_flux_segments),
 				WriteData(fid,prefix,'data',self.mass_flux_segments,'name','md.qmu.mass_flux_segments','format','MatArray');
-				flag=true; 
-			else 
-				flag=false; 
+				flag=true;
+			else
+				flag=false;
 			end
 			WriteData(fid,prefix,'data',flag,'name','md.qmu.mass_flux_segments_present','format','Boolean');
 		end % }}}
 		function savemodeljs(self,fid,modelname) % {{{
-		
+
 			if self.isdakota,
 				error('qmu savemodeljs error message: not supported yet!');
Index: /issm/trunk-jpl/src/m/classes/qmu.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/qmu.py	(revision 24592)
+++ /issm/trunk-jpl/src/m/classes/qmu.py	(revision 24593)
@@ -149,5 +149,5 @@
 
             if md.cluster.np <= 1:
-                md.checkmessage('in parallel library mode, Dakota needs to run on at least 2 cpus, 1 cpu for the master, 1 cpu for the slave. Modify md.cluser.np accordingly.')
+                md.checkmessage('in parallel library mode, Dakota needs to run on at least 2 cpus, 1 cpu for the master, 1 cpu for the slave. Modify md.cluster.np accordingly.')
 
             if self.params.processors_per_evaluation < 1:
Index: /issm/trunk-jpl/src/m/miscellaneous/normfit_issm.py
===================================================================
--- /issm/trunk-jpl/src/m/miscellaneous/normfit_issm.py	(revision 24592)
+++ /issm/trunk-jpl/src/m/miscellaneous/normfit_issm.py	(revision 24593)
@@ -5,5 +5,4 @@
 
 def normfit_issm(x, alpha=None):
-
     if alpha is None:
         alpha = 0.05
Index: /issm/trunk-jpl/src/wrappers/matlab/Makefile.am
===================================================================
--- /issm/trunk-jpl/src/wrappers/matlab/Makefile.am	(revision 24592)
+++ /issm/trunk-jpl/src/wrappers/matlab/Makefile.am	(revision 24593)
@@ -5,5 +5,5 @@
 
 #define prefix (from http://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Defining-Directories.html)
-AM_CPPFLAGS+=  -DISSM_PREFIX='"$(prefix)"'
+AM_CPPFLAGS += -DISSM_PREFIX='"$(prefix)"'
 
 #matlab io{{{
@@ -12,12 +12,13 @@
 else
 noinst_LTLIBRARIES = libISSMMatlab.la
-lib_LTLIBRARIES = 
-endif
-
-io_sources= ./io/CheckNumMatlabArguments.cpp\
-				./io/WriteMatlabData.cpp\
-				./io/FetchMatlabData.cpp
-
-ALLCXXFLAGS= -fPIC -D_WRAPPERS_ $(CXXFLAGS) $(CXXOPTFLAGS) 
+lib_LTLIBRARIES =
+endif
+
+io_sources = \
+	./io/CheckNumMatlabArguments.cpp \
+	./io/FetchMatlabData.cpp \
+	./io/WriteMatlabData.cpp
+
+ALLCXXFLAGS= -fPIC -D_WRAPPERS_ $(CXXFLAGS) $(CXXOPTFLAGS)
 
 libISSMMatlab_la_SOURCES = $(io_sources)
@@ -37,28 +38,29 @@
 #}}}
 #Wrappers {{{
-lib_LTLIBRARIES += BamgMesher_matlab.la\
-						 BamgConvertMesh_matlab.la\
-						 BamgTriangulate_matlab.la\
-						 ContourToMesh_matlab.la\
-						 ContourToNodes_matlab.la\
-						 DistanceToMaskBoundary_matlab.la\
-						 ElementConnectivity_matlab.la\
-						 ExpSimplify_matlab.la\
-						 ExpToLevelSet_matlab.la\
-						 InterpFromGridToMesh_matlab.la\
-						 InterpFromMeshToMesh2d_matlab.la\
-						 InterpFromMeshToMesh3d_matlab.la\
-						 InterpFromMeshToGrid_matlab.la\
-						 InterpFromMesh2d_matlab.la\
-						 IssmConfig_matlab.la\
-						 NodeConnectivity_matlab.la\
-						 M1qn3_matlab.la\
-						 MeshPartition_matlab.la\
-						 MeshProfileIntersection_matlab.la\
-						 PointCloudFindNeighbors_matlab.la\
-						 PropagateFlagsFromConnectivity_matlab.la\
-						 Triangle_matlab.la\
-						 ProcessRifts_matlab.la\
-						 Scotch_matlab.la
+lib_LTLIBRARIES += \
+	BamgMesher_matlab.la \
+	BamgConvertMesh_matlab.la \
+	BamgTriangulate_matlab.la \
+	ContourToMesh_matlab.la \
+	ContourToNodes_matlab.la \
+	DistanceToMaskBoundary_matlab.la \
+	ElementConnectivity_matlab.la \
+	ExpSimplify_matlab.la \
+	ExpToLevelSet_matlab.la \
+	InterpFromGridToMesh_matlab.la \
+	InterpFromMeshToMesh2d_matlab.la \
+	InterpFromMeshToMesh3d_matlab.la \
+	InterpFromMeshToGrid_matlab.la \
+	InterpFromMesh2d_matlab.la \
+	IssmConfig_matlab.la \
+	NodeConnectivity_matlab.la \
+	M1qn3_matlab.la \
+	MeshPartition_matlab.la \
+	MeshProfileIntersection_matlab.la \
+	PointCloudFindNeighbors_matlab.la \
+	PropagateFlagsFromConnectivity_matlab.la \
+	Triangle_matlab.la \
+	ProcessRifts_matlab.la \
+	Scotch_matlab.la
 
 if CHACO
@@ -66,5 +68,5 @@
 endif
 if KRIGING
-lib_LTLIBRARIES +=  Kriging_matlab.la
+lib_LTLIBRARIES += Kriging_matlab.la
 endif
 if KML
@@ -74,5 +76,5 @@
 
 # Dependencies {{{
-deps =  $(MATHLIB)
+deps = $(MATHLIB)
 
 #Triangle library
@@ -81,15 +83,14 @@
 #Matlab part
 AM_LDFLAGS = -module $(MEXLINK) -shrext ${EXEEXT} --export-dynamic -rdynamic -no-undefined
-if VERSION
-AM_LDFLAGS +=
-else
+
+if !VERSION
 AM_LDFLAGS += -avoid-version
 endif
 
 if STANDALONE_MODULES
-AM_LDFLAGS += -Wl,-static
-endif
-
-AM_CXXFLAGS +=  -D_HAVE_MATLAB_MODULES_ -fPIC
+AM_LDFLAGS += -Wl,-static -Wl,--disable-new-dtags -Wl,-rpath,'$$ORIGIN'
+endif
+
+AM_CXXFLAGS += -D_HAVE_MATLAB_MODULES_ -fPIC
 
 deps += ./libISSMMatlab.la ../../c/libISSMModules.la ../../c/libISSMCore.la ./libISSMApi.la
@@ -111,81 +112,82 @@
 
 #Optimization flags:
-AM_CXXFLAGS += $(CXXOPTFLAGS) 
+AM_CXXFLAGS += $(CXXOPTFLAGS)
 #}}}
 # Module sources and dependencies {{{
 if !WINDOWS
-libISSMMatlab_la_LIBADD = ./../../c/libISSMCore.la ./../../c/libISSMModules.la $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(MKLLIB) $(GSLLIB) $(PROJ4LIB) $(MATHLIB) $(MEXLIB) 
+libISSMMatlab_la_LIBADD = ./../../c/libISSMCore.la ./../../c/libISSMModules.la $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(MKLLIB) $(GSLLIB) $(PROJ4LIB) $(MATHLIB) $(MEXLIB)
 endif
 
 if STANDALONE_LIBRARIES
-libISSMMatlab_la_LDFLAGS = -static 
-deps += $(PETSCLIB) $(TAOLIB) $(NEOPZLIB) $(M1QN3LIB) $(SEMICLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(TRIANGLELIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB)   $(ADOLCLIB) $(AMPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
-endif
-
-if !WINDOWS
-libISSMApi_la_LIBADD = $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(MATHLIB) $(MEXLIB)
-endif
-
-if STANDALONE_LIBRARIES
-libISSMApi_la_LDFLAGS = -static 
-endif
+libISSMMatlab_la_LDFLAGS = -static
+libISSMApi_la_LDFLAGS = -static
+deps += $(PETSCLIB) $(TAOLIB) $(NEOPZLIB) $(M1QN3LIB) $(SEMICLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(TRIANGLELIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(ADOLCLIB) $(AMPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
+endif
+
+if !WINDOWS
+libISSMApi_la_LIBADD = $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(MATHLIB) $(MEXLIB)
+endif
+
+BamgConvertMesh_matlab_la_SOURCES = ../BamgConvertMesh/BamgConvertMesh.cpp
+BamgConvertMesh_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+BamgConvertMesh_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 BamgMesher_matlab_la_SOURCES = ../BamgMesher/BamgMesher.cpp
 BamgMesher_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-BamgMesher_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-
-BamgConvertMesh_matlab_la_SOURCES = ../BamgConvertMesh/BamgConvertMesh.cpp
-BamgConvertMesh_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-BamgConvertMesh_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+BamgMesher_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 BamgTriangulate_matlab_la_SOURCES = ../BamgTriangulate/BamgTriangulate.cpp
 BamgTriangulate_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-BamgTriangulate_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+BamgTriangulate_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 if CHACO
 Chaco_matlab_la_SOURCES = ../Chaco/Chaco.cpp
 Chaco_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-Chaco_matlab_la_LIBADD = ${deps} $(MPILIB) $(CHACOLIB) $(GSLLIB) $(PROJ4LIB) $(PETSCLIB) $(NEOPZLIB)
+Chaco_matlab_la_LIBADD = ${deps} $(CHACOLIB) $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 endif
 
 ContourToMesh_matlab_la_SOURCES = ../ContourToMesh/ContourToMesh.cpp
 ContourToMesh_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-ContourToMesh_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+ContourToMesh_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+
+ContourToNodes_matlab_la_SOURCES = ../ContourToNodes/ContourToNodes.cpp
+ContourToNodes_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+ContourToNodes_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+
+DistanceToMaskBoundary_matlab_la_SOURCES = ../DistanceToMaskBoundary/DistanceToMaskBoundary.cpp
+DistanceToMaskBoundary_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+DistanceToMaskBoundary_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+
+ElementConnectivity_matlab_la_SOURCES = ../ElementConnectivity/ElementConnectivity.cpp
+ElementConnectivity_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+ElementConnectivity_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 ExpToLevelSet_matlab_la_SOURCES = ../ExpToLevelSet/ExpToLevelSet.cpp
 ExpToLevelSet_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-ExpToLevelSet_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-
-ContourToNodes_matlab_la_SOURCES = ../ContourToNodes/ContourToNodes.cpp
-ContourToNodes_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-ContourToNodes_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-
-DistanceToMaskBoundary_matlab_la_SOURCES = ../DistanceToMaskBoundary/DistanceToMaskBoundary.cpp
-DistanceToMaskBoundary_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-DistanceToMaskBoundary_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-
-ElementConnectivity_matlab_la_SOURCES = ../ElementConnectivity/ElementConnectivity.cpp
-ElementConnectivity_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-ElementConnectivity_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+ExpToLevelSet_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+
+ExpSimplify_matlab_la_SOURCES = ../ExpSimplify/ExpSimplify.cpp
+ExpSimplify_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+ExpSimplify_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(NEOPZLIB)
 
 InterpFromGridToMesh_matlab_la_SOURCES = ../InterpFromGridToMesh/InterpFromGridToMesh.cpp
 InterpFromGridToMesh_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromGridToMesh_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+InterpFromGridToMesh_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+
+InterpFromMesh2d_matlab_la_SOURCES = ../InterpFromMesh2d/InterpFromMesh2d.cpp
+InterpFromMesh2d_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+InterpFromMesh2d_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+
+InterpFromMeshToGrid_matlab_la_SOURCES = ../InterpFromMeshToGrid/InterpFromMeshToGrid.cpp
+InterpFromMeshToGrid_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+InterpFromMeshToGrid_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 InterpFromMeshToMesh2d_matlab_la_SOURCES = ../InterpFromMeshToMesh2d/InterpFromMeshToMesh2d.cpp
 InterpFromMeshToMesh2d_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromMeshToMesh2d_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+InterpFromMeshToMesh2d_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 InterpFromMeshToMesh3d_matlab_la_SOURCES = ../InterpFromMeshToMesh3d/InterpFromMeshToMesh3d.cpp
 InterpFromMeshToMesh3d_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromMeshToMesh3d_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-
-InterpFromMeshToGrid_matlab_la_SOURCES = ../InterpFromMeshToGrid/InterpFromMeshToGrid.cpp
-InterpFromMeshToGrid_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromMeshToGrid_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-
-InterpFromMesh2d_matlab_la_SOURCES = ../InterpFromMesh2d/InterpFromMesh2d.cpp
-InterpFromMesh2d_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromMesh2d_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+InterpFromMeshToMesh3d_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 IssmConfig_matlab_la_SOURCES = ../IssmConfig/IssmConfig.cpp
@@ -193,50 +195,46 @@
 IssmConfig_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB)
 
-ExpSimplify_matlab_la_SOURCES = ../ExpSimplify/ExpSimplify.cpp
-ExpSimplify_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-ExpSimplify_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(NEOPZLIB)
-
 Kriging_matlab_la_SOURCES = ../Kriging/Kriging.cpp
 Kriging_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-Kriging_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
+Kriging_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
+
+M1qn3_matlab_la_SOURCES = ../M1qn3/M1qn3.cpp
+M1qn3_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
+M1qn3_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(METISLIB) $(M1QN3LIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 MeshPartition_matlab_la_SOURCES = ../MeshPartition/MeshPartition.cpp
 MeshPartition_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-MeshPartition_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(METISLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-
-M1qn3_matlab_la_SOURCES = ../M1qn3/M1qn3.cpp
-M1qn3_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-M1qn3_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(METISLIB) $(M1QN3LIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+MeshPartition_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(METISLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 MeshProfileIntersection_matlab_la_SOURCES = ../MeshProfileIntersection/MeshProfileIntersection.cpp
 MeshProfileIntersection_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-MeshProfileIntersection_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+MeshProfileIntersection_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 NodeConnectivity_matlab_la_SOURCES = ../NodeConnectivity/NodeConnectivity.cpp
 NodeConnectivity_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-NodeConnectivity_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+NodeConnectivity_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 PointCloudFindNeighbors_matlab_la_SOURCES = ../PointCloudFindNeighbors/PointCloudFindNeighbors.cpp
 PointCloudFindNeighbors_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-PointCloudFindNeighbors_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+PointCloudFindNeighbors_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 PropagateFlagsFromConnectivity_matlab_la_SOURCES = ../PropagateFlagsFromConnectivity/PropagateFlagsFromConnectivity.cpp
 PropagateFlagsFromConnectivity_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-PropagateFlagsFromConnectivity_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+PropagateFlagsFromConnectivity_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 Scotch_matlab_la_SOURCES = ../Scotch/Scotch.cpp
 Scotch_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-Scotch_matlab_la_LIBADD = ${deps} $(SCOTCHLIB) $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(BLASLAPACKLIB)
+Scotch_matlab_la_LIBADD = ${deps}  $(PETSCLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(BLASLAPACKLIB)
 
 ShpRead_matlab_la_SOURCES = ../ShpRead/ShpRead.cpp
 ShpRead_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-ShpRead_matlab_la_LIBADD = ${deps} $(SHAPELIBLIB) $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+ShpRead_matlab_la_LIBADD = ${deps} $(SHAPELIBLIB) $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 Triangle_matlab_la_SOURCES = ../Triangle/Triangle.cpp
 Triangle_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-Triangle_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(TRIANGLELIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+Triangle_matlab_la_LIBADD = ${deps} $(TRIANGLELIB) $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 ProcessRifts_matlab_la_SOURCES = ../ProcessRifts/ProcessRifts.cpp
 ProcessRifts_matlab_la_CXXFLAGS = ${AM_CXXFLAGS}
-ProcessRifts_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
-#}}}
+ProcessRifts_matlab_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+#}}}
Index: /issm/trunk-jpl/src/wrappers/python/Makefile.am
===================================================================
--- /issm/trunk-jpl/src/wrappers/python/Makefile.am	(revision 24592)
+++ /issm/trunk-jpl/src/wrappers/python/Makefile.am	(revision 24593)
@@ -5,14 +5,16 @@
 
 #define prefix (from http://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Defining-Directories.html)
-AM_CPPFLAGS+=  -DISSM_PREFIX='"$(prefix)"'
+AM_CPPFLAGS += -DISSM_PREFIX='"$(prefix)"'
 
 #python io{{{
 lib_LTLIBRARIES = libISSMPython.la
 
-io_sources= ./io/WritePythonData.cpp\
-				./io/CheckNumPythonArguments.cpp\
-				./io/FetchPythonData.cpp
+io_sources = \
+	./io/CheckNumPythonArguments.cpp \
+	./io/FetchPythonData.cpp \
+	./io/WritePythonData.cpp
 
-ALLCXXFLAGS= -fPIC -D_WRAPPERS_ $(CXXFLAGS) $(CXXOPTFLAGS) 
+ALLCXXFLAGS= -fPIC -D_WRAPPERS_ $(CXXFLAGS) $(CXXOPTFLAGS)
+
 libISSMPython_la_SOURCES = $(io_sources)
 libISSMPython_la_CXXFLAGS= $(ALLCXXFLAGS)
@@ -20,6 +22,5 @@
 #api io{{{
 lib_LTLIBRARIES += libISSMApi.la
-
-api_sources= ./io/ApiPrintf.cpp
+api_sources		 = ./io/ApiPrintf.cpp
 
 libISSMApi_la_SOURCES = $(api_sources)
@@ -27,145 +28,147 @@
 #}}}
 #Wrappers {{{
-if WRAPPERS
-lib_LTLIBRARIES += BamgConvertMesh_python.la\
-						BamgMesher_python.la\
-						BamgTriangulate_python.la\
-						ContourToMesh_python.la\
-						ContourToNodes_python.la\
-						ElementConnectivity_python.la\
-						ExpToLevelSet_python.la\
-						InterpFromMeshToMesh2d_python.la\
-						InterpFromMeshToMesh3d_python.la\
-						InterpFromGridToMesh_python.la\
-						InterpFromMeshToGrid_python.la\
-						IssmConfig_python.la\
-						MeshPartition_python.la\
-						MeshProfileIntersection_python.la\
-						NodeConnectivity_python.la\
-						Triangle_python.la\
-						ProcessRifts_python.la
+lib_LTLIBRARIES += \
+	BamgConvertMesh_python.la \
+	BamgMesher_python.la \
+	BamgTriangulate_python.la \
+	ContourToMesh_python.la \
+	ContourToNodes_python.la \
+	ElementConnectivity_python.la \
+	ExpToLevelSet_python.la \
+	InterpFromMeshToMesh2d_python.la \
+	InterpFromMeshToMesh3d_python.la \
+	InterpFromGridToMesh_python.la \
+	InterpFromMeshToGrid_python.la \
+	IssmConfig_python.la \
+	MeshPartition_python.la \
+	MeshProfileIntersection_python.la \
+	NodeConnectivity_python.la \
+	Triangle_python.la \
+	ProcessRifts_python.la
 
 if CHACO
 lib_LTLIBRARIES += Chaco_python.la
 endif
-endif 
 #}}}
 #Flags and libraries {{{
-deps =  $(MATHLIB) ${PYTHONLIB}
+deps = $(MATHLIB) ${PYTHONLIB}
 
 #Triangle library
-AM_CXXFLAGS =  -DTRILIBRARY -DANSI_DECLARATORS -DNO_TIMER -D_WRAPPERS_
+AM_CXXFLAGS = -DTRILIBRARY -DANSI_DECLARATORS -DNO_TIMER -D_WRAPPERS_
 
 #Python part
-AM_LDFLAGS   = $(PYTHONLINK) -shrext ${EXEEXT} -module
-if VERSION
-AM_LDFLAGS +=
-else
+AM_LDFLAGS = $(PYTHONLINK) -shrext ${EXEEXT} -module
+
+if !VERSION
 AM_LDFLAGS += -avoid-version
 endif
 
 if STANDALONE_MODULES
-AM_LDFLAGS += -Wl,-static
+AM_LDFLAGS += -Wl,-static -Wl,--disable-new-dtags -Wl,-rpath,'$$ORIGIN'
 endif
 
-deps += ./libISSMPython.la 
-AM_LDFLAGS += --no-warnings 
+AM_LDFLAGS 	+= --no-warnings
+AM_CXXFLAGS += -D_HAVE_PYTHON_MODULES_ -fPIC
 
-AM_CXXFLAGS +=  -D_HAVE_PYTHON_MODULES_   -fPIC
 if PYTHON3
-AM_CXXFLAGS +=  -DNPY_NO_DEPRECATED_API 
+AM_CXXFLAGS += -DNPY_NO_DEPRECATED_API
 endif
 
-deps += ../../c/libISSMModules.la ../../c/libISSMCore.la
+deps += ./libISSMPython.la ../../c/libISSMModules.la ../../c/libISSMCore.la ./libISSMApi.la
+
 if ADOLC
 deps += $(ADOLCLIB)
 endif
 
-deps += ./libISSMApi.la 
-
-if STANDALONE_LIBRARIES
-libISSMPython_la_LDFLAGS = -static 
-endif
-if STANDALONE_LIBRARIES
-libISSMApi_la_LDFLAGS = -static 
+if FORTRAN
+deps += $(FLIBS) $(FORTRANLIB)
 endif
 
 #Optimization flags:
-AM_CXXFLAGS += $(CXXOPTFLAGS) 
+AM_CXXFLAGS += $(CXXOPTFLAGS)
 #}}}
-#Bin sources {{{
+# Module sources and dependencies {{{
+libISSMPython_la_LIBADD = ./../../c/libISSMCore.la ./../../c/libISSMModules.la $(PETSCLIB) $(MPILIB) $(NEOPZLIB) $(MKLLIB) $(GSLLIB) $(PROJ4LIB) $(MATHLIB)
+
+if STANDALONE_LIBRARIES
+libISSMPython_la_LDFLAGS = -static
+libISSMApi_la_LDFLAGS = -static
+deps += $(DAKOTALIB) $(PETSCLIB) $(TAOLIB) $(NEOPZLIB) $(M1QN3LIB) $(SEMICLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(TRIANGLELIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(ADOLCLIB) $(AMPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
+endif
+
+libISSMApi_la_LIBADD = $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(MATHLIB)
+
 BamgConvertMesh_python_la_SOURCES = ../BamgConvertMesh/BamgConvertMesh.cpp
 BamgConvertMesh_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-BamgConvertMesh_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+BamgConvertMesh_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 BamgMesher_python_la_SOURCES = ../BamgMesher/BamgMesher.cpp
 BamgMesher_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-BamgMesher_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+BamgMesher_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 BamgTriangulate_python_la_SOURCES = ../BamgTriangulate/BamgTriangulate.cpp
 BamgTriangulate_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-BamgTriangulate_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+BamgTriangulate_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 if CHACO
 Chaco_python_la_SOURCES = ../Chaco/Chaco.cpp
 Chaco_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-Chaco_python_la_LIBADD = ${deps} $(MPILIB)  $(CHACOLIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+Chaco_python_la_LIBADD = ${deps} $(CHACOLIB) $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 endif
 
 ContourToMesh_python_la_SOURCES = ../ContourToMesh/ContourToMesh.cpp
 ContourToMesh_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-ContourToMesh_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+ContourToMesh_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 ContourToNodes_python_la_SOURCES = ../ContourToNodes/ContourToNodes.cpp
 ContourToNodes_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-ContourToNodes_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+ContourToNodes_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 ElementConnectivity_python_la_SOURCES = ../ElementConnectivity/ElementConnectivity.cpp
 ElementConnectivity_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-ElementConnectivity_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+ElementConnectivity_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 ExpToLevelSet_python_la_SOURCES = ../ExpToLevelSet/ExpToLevelSet.cpp
 ExpToLevelSet_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-ExpToLevelSet_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+ExpToLevelSet_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB) $(NEOPZLIB)
 
+InterpFromGridToMesh_python_la_SOURCES = ../InterpFromGridToMesh/InterpFromGridToMesh.cpp
+InterpFromGridToMesh_python_la_CXXFLAGS = ${AM_CXXFLAGS}
+InterpFromGridToMesh_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
+
+InterpFromMeshToGrid_python_la_SOURCES = ../InterpFromMeshToGrid/InterpFromMeshToGrid.cpp
+InterpFromMeshToGrid_python_la_CXXFLAGS = ${AM_CXXFLAGS}
+InterpFromMeshToGrid_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 InterpFromMeshToMesh2d_python_la_SOURCES = ../InterpFromMeshToMesh2d/InterpFromMeshToMesh2d.cpp
 InterpFromMeshToMesh2d_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromMeshToMesh2d_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
+InterpFromMeshToMesh2d_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
 
 InterpFromMeshToMesh3d_python_la_SOURCES = ../InterpFromMeshToMesh3d/InterpFromMeshToMesh3d.cpp
 InterpFromMeshToMesh3d_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromMeshToMesh3d_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
-
-InterpFromGridToMesh_python_la_SOURCES = ../InterpFromGridToMesh/InterpFromGridToMesh.cpp
-InterpFromGridToMesh_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromGridToMesh_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
-
-InterpFromMeshToGrid_python_la_SOURCES = ../InterpFromMeshToGrid/InterpFromMeshToGrid.cpp
-InterpFromMeshToGrid_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-InterpFromMeshToGrid_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
+InterpFromMeshToMesh3d_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(MULTITHREADINGLIB) $(GSLLIB) $(PROJ4LIB)
 
 IssmConfig_python_la_SOURCES = ../IssmConfig/IssmConfig.cpp
 IssmConfig_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-IssmConfig_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB)
+IssmConfig_python_la_LIBADD = ${deps} $(DAKOTALIB) $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB)
 
 MeshPartition_python_la_SOURCES = ../MeshPartition/MeshPartition.cpp
 MeshPartition_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-MeshPartition_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+MeshPartition_python_la_LIBADD = ${deps} $(PETSCLIB) $(METISLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 MeshProfileIntersection_python_la_SOURCES = ../MeshProfileIntersection/MeshProfileIntersection.cpp
 MeshProfileIntersection_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-MeshProfileIntersection_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+MeshProfileIntersection_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 NodeConnectivity_python_la_SOURCES = ../NodeConnectivity/NodeConnectivity.cpp
 NodeConnectivity_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-NodeConnectivity_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+NodeConnectivity_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 Triangle_python_la_SOURCES = ../Triangle/Triangle.cpp
 Triangle_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-Triangle_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(TRIANGLELIB) $(GSLLIB) $(PROJ4LIB)
+Triangle_python_la_LIBADD = ${deps} $(TRIANGLELIB) $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 
 ProcessRifts_python_la_SOURCES = ../ProcessRifts/ProcessRifts.cpp
 ProcessRifts_python_la_CXXFLAGS = ${AM_CXXFLAGS}
-ProcessRifts_python_la_LIBADD = ${deps} $(MPILIB) $(PETSCLIB) $(GSLLIB) $(PROJ4LIB)
+ProcessRifts_python_la_LIBADD = ${deps} $(PETSCLIB) $(BLASLAPACKLIB) $(MPILIB) $(NEOPZLIB) $(GSLLIB) $(PROJ4LIB)
 #}}}
