Use a separate folder for each individual solver. For a simulation suite such as ACE3P, use one top-level folder for the suite, with a separate folder underneath for each individual solver.
The root folder for each solver should contain 3 files:
A .crf file with the name of the solver as its prefix, for example, "IBAMR.crf". This is the simulation template for users to load into CMB/ModelBuilder.
A .py file with the name of the solver as its prefix, for example "IBAMR.py". This is the top-level script to be executed by the CMB/ModelBuilder "Export Simulation" command.
A README.md file with a brief description of the solver and links to its documentation.
The root folder for each solver should also contain a subfolder, with the name "internal", for organizing the remaining files. The standard layout of the internal folder is:
__init__.py -- a small python file with one line to import scripts from the writers subfolder.
solver-simbuilder.sbt -- The top-level template file for the simulation attributes.
(Replace "solver" with the name of the solver in lower case, for example, ibamr-simbuilder.sbt.)
Include a reference to this file in the top-level Solver.crf file.
By using a single .sbt file as the root for all simulation attributes, developers can view the attribute UI using the SMTK attribute preview program (qtAttributePreview).
Standard practice is that the solver-simulation.sbt file include definition files located in the templates subfolder.
scripts/ (optional) -- A folder for any script files needed to generate the workflow files or related output.
Examples include shell scripts to run the jade template engine (to generate .sbt files from .jade sources), and python scripts to merge the individual template files into a single .crf file for sharing/previewing with users during development.
templates/ -- Folder for attribute definition files included in the solver-simulation.sbt file.
test/ -- Folder for scripts, data files, readme, and other files used to test/verify the solver template and writer logic.
writers/ -- Folder for python scripts used to generate the simulation input file(s). The contents of this folder should be authored as a python module that will be imported by the top-level Solver.py script.
unused/ (optional) -- Folder for any local files used for temporary development and test. If an unused subfolder is present, add a .gitignore file to the internal folder to keep the unused contents out of source control.
As an example, the basic filesystem layout for a solver named "ExampleSolver" would be
The top-level elements contains 2 elements with id "simbuilder" and "export", respectively. These ids are used by ModelBuilder.
The simbuilder element contains an element that references the internal .sbt file for simulation attributes.
Because the contents of the export element are typically simple and short, standard convention is to enumerate them in the Solver.crf. However, if the export definitions for a given solver are much longer than those in the above example, put them in a separate solver-export.sbt file and include that by reference in the Solver.crf file.
The export attributes contain one attribute definition, an with name "ExportSpec". ModelBuilder uses this name when initializing an export process.
The ExportSpec definition contains an element for setting the model for the export script. If the export processing does not require a model, omit this element.
The ExportSpec definition contains an "AnalysisTypes" item definition. ModelBuilder looks for this item, and if found, constructs a panel for the user to select the analysis type(s) in the export dialog. Note that this item definition is optional, and can be omitted for cases where there aren't multiple analysis cases.
Also note that this definition has an AdvanceLevel of 99, to prevent it from being displayed in the standard SMTK attribute UI.
The ExportSpec definition contains a "mesh" item definition for specifying the CMB mesh to the export script. If the application does not require a mesh, omit this item definition.
The ExportSpec definition contains a "PythonScript" item definition. ModelBuilder uses this definition as the python script for writing solver input files. Set the default value of this definition to the name of the top-level Solver.py script, so that ModelBuilder can search for it on the local filesystem.
The ExportSpec definition may contain other item definitions for use by the python export scripts. In the example above, an "OutputFile" item definition is included; this would be used when the output is a single file. For generating multiple output files, a common alternative is to use 2 item definitions to specify (i) an output directory on the local file system, and (ii) a filename prefix to use with each output file.
The export template also includes a section to specify a single instanced view for displaying the ExportSpec UI.
Standard practice is that this file has 2 sections
An element for including files in the templates subfolder
A section for specifying the UI elements
Put the remaining template/definition files in the templates subfolder.
Use the .sbt extension for each template file in the templates subfolder.
In the typical/preferred case, use separate files for problem, solver, and output specifications.
Problem specifications are typically partitioned further according to the model entity dimension. For example, use separate .sbt files for material definitions (volume entities) and boundary conditions (surface entities).
Lowercase filenames are typically used in the templates folder. The solver name is typically not included in the filenames in the templates folder.
During development, it is important that the python modules/files are reloaded on each new invocation of the simulation export function. This functionality is not directly provided by python, and the current convention is to use the python reload() method to assure this. For example, use two lines in the __init__.py file in the internal folder:
The top-level python script is the entry point for ModelBuilder to generate solver input files.
Include a function named ExportCMB, which is called by ModelBuilder
The "spec" argument is a wrapper object defined in the SMTK source code, with methods to retrieve the simulation attribute system, the export attribute system, and an SMTK Logger instance.
Return an integer error code from the ExportCMB() method.
Use the SMTK Logger object from the ExportSpec object to record warning and error messages. Also note that print statements in the writer scripts are displayed in the ModelBuilder output window. Common practice is to print and write messages to the logger.
Include the following line near the top of the Solver.py file to prevent python from writing cache files for imported modules
sys.dont_write_bytecode = True
Note that this is not the ideal way to prevent cache files, but this will be used until/unless ModelBuilder is updated to prevent python-cache files.
The preferred convention is to make the ExportCMB() method very short, by instantiating and calling a writing object in the writers subfolder.
The preferred convention is to include a table of format-specification data in the Solver.py file, so that casual developers can make minor updates by editing this file only.