Writing a Custom Task
This page explains how to create a new custom task and integrate it into NairnMPM. Custom tasks can be used to add many new features to the code, including now ways to export results for visualization.
Basic Steps
The first steps create the task and allow it to be used in calculations
- Create a new source code class that inherits from the CustomTask class (or a subclass of that class).
- Create instance of this new task in MPMReadHandler::myStartElement()when an input file wants to use the new task:
- See code section that handles the Schedule element
- Create new instance of your task as determined by the name attribute of Schedule element
- This change should be the only change done to the core code.
- Support methods listed below (as needed) in the new custom task. Most methods return the nextTask because the calling code uses it when it loops over all custom tasks. Any that are not needed can be omitted because the CustomTask class provides methods that simply returns the nextTask. Custom tasks are done at the end of each time step and handled by the RunCustomTasksTask class.
Task Parameters
If the custom task has parameters, implement them by reading them with:
- char *CustomTask::InputParam(char *pName,int &input)
- Check the parameter name in pName. If it matches a defined task parameter name set input to the kind of pointer needed and return the actual pointer to the class variable for that parameter. If no match return NULL. This is the only method that does not return nextTask.
Initialize
This method is called once at beginning of the entire MPM analysis:
- CustomTask *CustomTask::Initialize()
- Do any initialization and print info about the task using cout. Anything printed will by in the custom tasks section of the results file.
MPM Time Step Tasks
In each time step, a custom task is called through various methods. Your new task can implement those that are needed.
Prepare Custom Task
This method is called just before custom tasks are started:
- CustomTask *MyTask::PrepareForStep(bool &doExtraps)
- Initialize variables used by the task in the current time step. If the task needs extrapolations to the grid, set doExtraps to TRUE. Note that extrapolations to the grid in custom tasks are not done in parallel. Tasks that need to extrapolate to the gird should normally only be for periodic tasks, such as archiving grid results. Extrapolations that are done every time step might impact performance. If such tasks become essential, it will be better to incorporate them in the code as an actual (and parallel) tasks instead of a custom task. The custom task approach, however, can still be useful for developing a new feature.
Custom Extrapolatlions
The following methods are in a loop which allows a custom task to extrapolate some property to the grid (see VTKArchive Custom Task code for example of a task that uses loop extrapolation). Note there is no automatic handling for looping over particles, but a task can easily implement that loop on its own (see AdjustTimeStep Custom Task code for example of a task that implements a particle loop).
- CustomTask *MyTask::BeginExtrapolations(void)
- Called once before the extrapolation loop begins. Initialize any required extrapolation variables.
- CustomTask *MyTask::NodalExtrapolation(NodalPoint *ndmi,MPMBase *mpnt,short vfld,int matfld,double wt)
- Called repeatedly in the loop for each particle/node pair. vfld is the velocity field, matfld is material valocity filed (when in multimaterial mode), and wt is the weight (or mass times shape function). You can use this method to extrapolate particle data to the grid.
- CustomTask *MyTask::EndExtrapolations(void)
- Called once when extrapolations are over. This method should free anything allocated during the extrapolations or to do some calculations.
Custom Task Calculations
This method is the usually the main part of any custom task:
- CustomTask *MyTask::StepCalculation(void)
- Do the desired calculations. The code will have access to all global variables.
Custom Task Clean Up
This method is called at the end of the time step:
- CustomTask *MyTask::FinishForStep(void)
- You should free up any memory still allocated by the task.