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:
- Add the field to
field_typedata 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;
- Next, you need to add your field to
Grid_InitializeUniformGrid.C. At the top of the file you need to declare an
intto hold the number which is used to reference the field, for example
SodiumDensityexample. 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..
- 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.
- You can access the field in your problem initializer or elsewhere using the
FindFieldfunction. 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.
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
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.