How to bring in an external component

Overview

Each external components invocable from FACETS must comply to the API described at Interface and naming scheme.

Following are the basic steps to bring in an external component.

  • Step 1: Identify all the in/out data that interact with a transport simulation, how data get initialized, how to advance the component up to a given time, and how to dump and restart the component.
  • Step 2: Provide, if necessary, C/C++ wrapper calls to populate and extract the above data, advance the component, restart, etc. The wrapper should

derive from facetsifc/FacetsIfc.h and one of dimensional interfaces (facetsifc/Facets0fIfc.h, for example).

  • Step 3: Identify the type of component. Presently the type of component must be one of core, edge, source, or wall. A corresponding class called FcXIfc will exist in the FACETS repo, where X is one of {Core, Edge, Source, Wall}.
  • Step 4: Write a C++ class named FcYComponent, which inherits from FcXIfc where Y is the name of the component (e.g. Nubeam) and FcComponent. This class should implement all the abstract methods declared in FcXIfc.

This class lives in FACETS and delegates methods implementations to the wrapper class.

UEDGE example

For example, in the case of UEDGE, the wrapper class is of type CxxUedge (in facetsall/uedge/ucxxst). It derives from FacetsIfc and Facets0dIf classes from facetsifc and should implement all their methods. In addition, the wrapper should have get and set methods to all variable that can be requested in the coupling data exchange. These variables can be seen in coupling interfaces that are supported by this component. For example, uedge component should have methods to get and set variable that are needed in coupling with core and wall.

The wrapper UedgeIfc class is used in FcUEDGEComponent class in facetsall/facets/fcedge:

class FcUEDGEComponent : public FcEdgeIfc { 
  private:
    UedgeIfc* uePtr;
};

All methods that are supposed to be implemented are delegated to this wrapper object. For example:

int
FcUEDGEComponent::complete() {
  return uePtr->complete(comm);
}

etc.

All methods from FcEdgeIfc should be implemented. This means implementing methods from FcComponent, FcCoreEdgeIfc and !Fc0dIfc.

WallPsi example (more detailed and more typical)

The wrapper class

The wrapper class is in facetsall/wallpsi/fcwallifc and is called FcWallPsi. It implements two interfaces, FacetsIfc and Facets0dIfc.

Facets component

The component is in facetsall/facets/fcwall, !FcWallPSIComponent (need to rename it to FcWallPsiComponent for consistency!) and contains a pointer to the wrapper:

class FcWallPSIComponent: publis FcWallIfc {
  private:
    FcWallPsi* wallPtr;
};

All methods are implemented by delegation to this pointer:

int
FcWallPSIComponent::setMpiComm(long comm) {
  return wallPtr->setMpiComm(comm);
}

All methods from FcEdgeIfc should be implemented. This means implementing methods from FcComponent, FcCoreEdgeIfc and !Fc0dIfc.

Other things not to forget in facetsall/facets

You need to make autotools aware of wallpsi by including this

builtin(include, config/tx_wallpsi.m4)

in configure.ac. Hopefully your component is autotooled and this file exists. This means that a similar line exists in facetsall/wallpsi/configure.ac.

In addition, facets/configure.ac should include:

AC_CONFIG_FILES(
fcwall/Makefile
}

You also need to edit facetsall/facets/config.h.in to have these lines:

/* Defined if wallpsi found */
#undef HAVE_WALLPSI

The component should be registered within facets. For example, fcwall subdir now has FcWallComponentRegistry which has a method for registering wall components. This method is called in facets/facets/FcFusionSimulation.cpp.

How to work with one component in facetsall

Please look for more details at  talk given at FACETS meeting August 2010.

We use bilder tool that manages consistent builds of facetsall codes. The facetsall codebase consists of:

autotools

plasma_state

facetsifc

wallpsi

fluxgrid

bbsolver

ga_trainsport

ntcc_transport

fmcfm

toric

nubeam

uedge

facets

fctests

These packages will be build if you check out facetsall and run mkfcall.sh with no arguments. All packages will be put under $HOME/software directory.

But what if you want to work with one component? For example, to build just uedge on iter under $HOME/software, you should use (this is just one command):

./mkfcall.sh -W wallpsi,facets,plasma_state,bhssolver,fluxgrid,fctests,fmcfm,nubeam,toric,ga_transport,fgtests,eqcodes -r -j 6 -k /contrib -i $HOME/software -e sveta@txcorp.com

This will force (via using -r) to build only uedge (as its builds are not set to NONE on the command line). Using -i /internal will allow the build to find all other things that uedge depends on (it depends on facetsifc, for example) without rebuilding them. The uedge installations will under $HOME/software/uedge.

Note that facets is not being built using command above. But if you intend to use fctests, you will need to build facets as well (get rid of FACETS_BUILDS=NONE in the command above in this case).

The installations (in $HOME/software) are created from build directories facetsall/builds/uedge subdirectory which will contain three subdirs:

 
iter.sveta$ pwd
/home/research/sveta/projects/facetsall
iter.sveta$ cd builds/uedge/
iter.sveta$ ls 
nopetsc  par  ser
iter.sveta$ 

each having Makefile. These makefiles can be reused once you do modifications in the uedge source. All you have to do is to run "make" and "make install" from these subdirs.

Tests

In order to run tests (facetsall/fctests) you need have results and fctests checked out. I usually work with facetsall, which comes with fctests and I check out the results there as well:

cd facetsall
svn co https://ice.txcorp.com/code/fcresults/iter fcresults-iter

To run tests:

cd fctests
config/cleanconf.sh -a
/home/research/sveta/projects/facetsall/fctests/configure '--with-source-dir=/home/research/sveta/projects/facetsall/facets' '--with-serial-dir=/home/research/sveta/projects/facetsall/builds/facets/ser' '--with-parallel-dir=/home/research/sveta/projects/facetsall/builds/facets/par' '--with-fluxgrid=/home/research/sveta/volatile/fluxgrid/bin/fluxgrid' '--with-supra-search-path=/home/research/sveta/volatile:/usr/local/contrib' '--with-results-dir=/home/research/sveta/projects/facetsall/fcresults-iter'
cd tests
make clean
make check

You will need to make corrections for your paths there... Look for failures in fctests/tests/check.failure and for the log in fctests/tests/check.log. Each subdir has its own log and failure files as well. Each test has a .out file which has more details then the log file.

If you want to run tests just for your component:

cd fctests/tests/edge
make clean
make check

To run just one test there, do something like:

cd fctests/tests/edge
make check-test TEST_NAME=uedge-exemplar-shs

The names of the tests come from scripts with .sh extensions.

My experience shows that sometimes tests get confused and report that no new h5 files get generated. What I do is

make clean
rm *h5
svn up
make check

This will ensure that all h5 files that are in the repo are back and all generated files are deleted before the tests run.

Attachments