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
typedefs.h
in thefield_type
data structure. To do this, look for the last field in the list beforeFieldUndefined
. Give your problem a new number and incrementFieldUndefined
. For example, let’s say you wanted to add a new field calledSodiumDensity
. If the last field in field_types isFieldUndefined = 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 anint
to hold the number which is used to reference the field, for exampleNaNum
for theSodiumDensity
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..
- 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
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.