# This software was produced by NIST, an agency of the U.S. government,
# and by statute is not subject to copyright in the United States.
# Recipients of this software assume all responsibilities associated
# with its operation, modification and maintenance. However, to
# facilitate maintenance we ask that before distributing modified
# versions of this software, you first contact the authors at
# oof_manager@nist.gov.

This README file and the directory it is in were created by running
oof2-extension-setup like this:

oof2-extension-setup --template=%TEMPLATE% --module=%MODULENAME% --class=%CLASS%

The files and subdirectories were generated from templates in the OOF2
distribution.  The templates are designed to make it easy (or easier)
to build certain kinds of extensions for OOF2.

Follow the steps below to write and build an OOF2 extension.

(0) This directory's name was determined by the --module argument
    given to oof2-extension-setup. The directory contains a
    CMakeLists.txt file, a source directory, and an empty "build"
    directory, as well as this README file.

(1) CMakeLists.txt includes a version number for the extension.  It's
    originally set to 0.0.0.  Edit the file to change the number if
    necessary.  The number is only there for your convenience.

(2) Move to the source subdirectory.

(3) Inside the source subdirectory there are files with the name of
    the module, plus a suffix: ".C" for C++ code, ".h" for C++
    headers, ".swg" for swig code, and ".spy" for python code that's
    included in the swig output.  Some files might not be present for
    some types of extensions.

    The files contain notes about what you will need to change in
    each.  In particular, when adding new Properties you will need to
    edit the .C file to change the functions that determine the
    behavior of the Property class.

    For more information on coding for OOF2, see the on-line OOF2
    manual, in particular the parts "Extending OOF2" (for an overview)
    and "OOF2 Extending Reference" (for all the details).

    We anticipate that most extensions will involve new Property
    classes.  Note the following points:

    (3a) If you need to add, remove, or alter the Property's
         parameters (which will be settable via the OOF2 GUI and
         scripts), you'll need to change the Property's constructor
         and its arguments in all four files in the source directory.
         Change the parameters in the argument list of the
         constructor, which appears in the .C, .h, and .swg files.
         The constructor should store the values of the parameters as
         data in the Property object.  Change the .h and .swg files so
         that they're consistent with the .C file.  You'll also have
         to change the parameter list in the PropertyRegistration in
         the .spy file.

    (3b) If you want to change where the Property appears in the
         hierarchy in the Material page, edit the "name" argument of
         the PropertyRegistration in the .spy file.  "name" is a
         string in which colons mark the levels of the Property
         hierarchy, as displayed on the OOF2 Materials page.  To
         change where the Property is listed among other Properties at
         the same level of the hierarchy, change the "ordering"
         argument.

    (3c) If you need to add additional C++ source files, put them in
         the source directory and add them to the SOURCES list in
         source/CMakeLists.txt.

    (3d) If you need to add any Python files, simply put them in the
         source directory or a subdirectory of it.  Subdirectories can
         be nested.  In OOF2 these files can be imported as submodules
         of %MODULENAME%.

    (3e) The extensions provided by the templates in this directory
         build new Property classes on top of base classes defined in
         OOF2/SRC/engine/properties that were specifically designed to
         be extended in this way.  The functions that you need to
         define in order to use the extensions are virtual methods
         called by the functions discussed in the "Adding New Material
         Properties" section of the manual.  See that section for a
         fuller discussion of Property classes, if the templates
         provided here are insufficient.

(4) Move to the build directory.  Type
        ccmake ..
    to start CMake, and press "c" to do the initial configuration.
    You probably don't need to change any parameters other than
    CMAKE_INSTALL_PREFIX and CMAKE_BUILD_TYPE.

    * CMAKE_BUILD_TYPE can be either Release or Debug.

    * CMAKE_INSTALL_PREFIX is the name of directory into which the
      extension will be installed.  It does *not* have to be the
      directory where OOF2 is installed.  When the extension is built,
      a subdirectory named %MODULENAME% will be created within the
      installation directory.

    * OOF2_PYTHON3_VERSION is preset to the version of Python that was
      used to build OOF2.  You should not have to change this, unless
      you are re-using a Property that you originally created with a
      different version of Python.  Make sure that the version of
      Python used here is the same as the one that was used when OOF2
      was built.

    If you need to change any parameters, do so, and press "c" again.
    Press "g" to generate the Makefile and exit ccmake.

(5) Run "make" and "make install".  If you're installing into a system
    directory, run "sudo make install" instead of "make install".  Fix
    the compilation errors and try again.

(6) The directory where the extension is installed, named by
    CMAKE_INSTALL_PREFIX in cmake, needs to be in the Python path,
    which is the list of directories that it searches for modules.
    You can print the path by typing
    
       python -c "import sys; print(sys.path)"
       
    in a terminal window.  If the extension directory isn't listed,
    you will need to add it.  There are a number of ways to do that.

    (a) To set the path for a single invocation of OOF2, use the
        --pathdir option when starting OOF2, like this:

           oof2 --pathdir=<prefix>

        <prefix> is the value of CMAKE_INSTALL_PREFIX used in cmake.
        Equivalently, set the path from the Unix shell by typing

            PYTHONPATH=<prefix> oof2 [other arguments go here]

        when starting OOF2.  (The syntax may depend on which shell
        you're using.)

    (b) To set the path for more than one invocation of OOF2 and
        simultaneously for all other Python programs, set the
        PYTHONPATH environment variable in the Unix shell before
        running OOF2.  The way to do that depends on which shell you
        use.  In bash, for example, you could type

            export PYTHONPATH=<prefix>:$PYTHONPATH

        This will set PYTHONPATH for all future commands run in the
        current terminal window.  To make that change permanent, put
        the "export" line in the .profile file in your home directory.
        That will set the path for all new terminal windows (but not
        ones that are already open).

    (c) To set the path for all future invocations of OOF2 but not for
        any other Python program, edit the .oof2rc file in your home
        directory, and add the line

            sys.path.append("<prefix>")

        where <prefix> is the value of CMAKE_INSTALL_PREFIX.  However
        this won't work if you load your extension module with
        --import (see below).

(7) Run OOF2 and load your extension.  How you do this depends on
    whether you want the extension to be loaded automatically every
    time you run OOF2 or not, and if you want the loading to be
    recorded in the OOF2 log file (so that the extension will be
    reloaded if the log file is re-run).

    The choices are: 

    (a) Put
 
             OOF.File.Load.Module(module="<module>")

        in the .oof2rc file in your home directory.  This will load
        the extension every time that you start OOF2.  In this case,
        it makes sense to set the path in .oof2rc as well (see
        above). The command will not be recorded in the log file, but
        the module will be reloaded when OOF2 is run again.

    (b) Start oof2 with the --import flag:
 
             oof2 --import <module>
 
        where <module> is the name you assigned to the --module option
        when you ran oof2-extension-setup.  This will load the
        extension just for this OOF2 session, and will not be recorded
        in the log file.  You can combine this with the --pathdir
        option if necessary.  (Because modules loaded with --import
        are loaded before .oof2rc is read, --import will not work if
        it requires a path that was set in .oof2rc.)

    (c) Use the File/Load/Module command in the main OOF2 menu bar.
        This can be done at any time during an OOF2 session, and will
        be recorded in the log file.

    (d) type

             import <module>
 
        in the OOF2 Console window.  This can be done at any time
        during an OOF2 session, but will *not* be recorded in the log
        file.

