How to add a new baryon field

If you wish to add a new field to Enzo, there are a few files that you will need to modify:

  1. Add the field to typedefs.h in the field_type data structure. To do this, look for the last field in the list before FieldUndefined. Give your problem a new number and increment FieldUndefined. For example, let’s say you wanted to add a new field called SodiumDensity. If the last field in field_types is FieldUndefined  = 96, you would add your field as
SodiumDensity = 96,
FieldUndefined = 97;
  1. Next, you need to add your field to Grid_InitializeUniformGrid.C. At the top of the file you need to declare an int to hold the number which is used to reference the field, for example NaNum for the SodiumDensity example. Further down, you need to add your field to the FieldType list. After the other fields have been added, add the line
FieldType[NaNum    = NumberOfBaryonFields++] = SodiumDensity;

In theory, you could add the fields and allocate the fields in your problem initializer code (as some test problems currently in Enzo do), but it is cleaner and simpler to have your problem initializer call InitializeUniformGrid before doing the setup for your problem type. For more details, see Adding a new Test Problem..

  1. Finally, you need to modify the initializer of problem types using your new field to make sure that the field is written out. Add the lines
char* SodiumName = "Sodium_Density";
...
DataLabel[i++] = SodiumName;

after the other DataLabels are set. Note that you need to set the Data Labels in the same order that the fields were added in Grid_InitializeUniformGrid.C or the fields will be written incorrectly.

  1. You can access the field in your problem initializer or elsewhere using the FindField function. To get the field number, you would use
int NaNum;
NaNum = FindField(SodiumDensity, FieldType, NumberOfBaryonFields);

Now you can access the field as BaryonField[NaNum]. For example, to set the value to 0 everywhere,

for (int i = 0; i < size; i++)
   BaryonField[NaNum][i] = 0.0;

For a more detailed discussion of how data in BaryonFields is accessed, see Accessing Data in BaryonField.

Conservation

For the purpose of advection and interpolation, Enzo assumes that all fields are densities unless told otherwise. If your field is not a density field, you will need to make some adjustments to make sure that the field is properly conserved. To do this, you can modify the macros in typedefs.h under FieldTypeIsDensity. Non-density fields will be multiplied by density prior to flux correction and converted back afterwards. This process will make the field be conserved in the same way as density fields. To see how Enzo decides whether a field needs to be multiplied by density, take a look at the file MakeFieldConservative.C. The actual manipulation is done in the flux correction and interpolation routines, and should not need to be modified.