yt_get_ParticlesPtr – Set Particle Information¶
yt_get_ParticlesPtr¶
int yt_get_ParticlesPtr( yt_particle **particle_list );
Usage: Get the
yt_particlearray pointer wherelibytaccess particles information from. Each MPI rank should call this function and fill them in. If you don’t have any particles, then skip this.Return:
YT_SUCCESSorYT_FAIL
Every MPI rank must call this API and fill in the particle information in the same order. We do not broadcast and sync information here.
yt_particle¶
const char* par_type(set bylibyt)Usage: Name of the particle type.
libytonly copies the pointer frompar_type_list’s data memberpar_typeto this variable and does not make a hard copy. You don’t need to assign it again.
The lifetime of
par_typeshould cover in situ analysis process.libytonly borrows this pointer and does not make a hard copy.int num_attr(set bylibyt)Usage: Number of attributes this particle type has.
libytwill assign your inputpar_type_list’s data membernum_attrto this variable. You may skip this.
yt_attribute* attr_list(initialized bylibyt)Usage: Attribute list of this particle. This is a
yt_attributearray with lengthnum_attr.Data member in
yt_attribute:const char* attr_name(Default=NULL)Usage: Attribute name.
The lifetime of
attr_nameshould cover in situ analysis process.libytonly borrows this variable and does not make a copy.yt_dtype attr_dtype(Default=YT_DOUBLE)Usage: Attribute’s data type.
Valid Value:
yt_dtype
const char* attr_unit(Default="")Usage: Unit of the attribute, using
ytunit system.
The lifetime of
attr_unitshould coveryt_commit.int num_attr_name_alias(Default=0)Usage: Number of name aliases.
const char **attr_name_alias(Default=NULL)Usage: A list of name aliases.
The lifetime of
attr_name_aliasshould coveryt_commit.const char *attr_display_name(Default=NULL)Usage: Display name on the output figure. If it is not set, then it will use
attr_nameinstead.
The lifetime of
attr_display_nameshould coveryt_commit.
const char *coor_x, *coor_y, *coor_z(Default=NULL)Usage: Attribute name representing coordinate or position x, y, and z.
The lifetime of
coor_x,coor_y,coor_zshould cover the in situ analysis process.libytonly borrows these names and does not make a copy.void (*get_par_attr) (const int, const long*, const char*, const char*, yt_array*)(Default=NULL)Usage: Function pointer to get or generate particle’s attribute.
libytborrows the full field and particle information class (class XXXFieldInfo) fromfrontend. It is OK not to set a particle’sattr_unit,num_attr_name_alias,attr_name_alias,attr_display_name, if thisattr_nameis already inside your frontend. If you are adding a totally new particle attribute, do add them.libytwill add these new attributes information alongside with your original one.Refer to Naming and Field Information for how particle/attribute names and yt fields are linked and reused.
Get Particle Attribute Function¶
For each particle type, there should be one get particle attribute function get_par_attr. This function is able to write particle attribute to an array, just through knowing the grid id, particle type, and attribute name.
Get particle attribute function must have a prototype like this:
void GetAttr(const int list_len, const long *list_gid, const char *par_type, const char *attr_name, yt_array *data_array);
get_par_attr(const int, const long*, const char*, const char*, yt_array*): generate particle attribute in that grid when input grid id, particle type, and particle attribute name.const int list_len: number of grid id inlist_gid.const long *list_gid: prepare particle data inside the grid id in this list.const char *par_type: target particle type to prepare.const char *attr_name: target attribute to prepare.yt_array *data_array: write generated particle data to the pointer in this array correspondingly. Fill in particle attribute insideyt_arrayarray using the same order as inlist_gid.
We should always write our particle attribute data in the same order, since we get attributes separately.
yt_array¶
Usage: a struct used in derived function and get particle attribute function.
Data Member:
long gid: grid id.long data_length: length ofdata_ptr.void *data_ptr: data pointer where you should write in particle data of this grid.
Example¶
par_io_get_par_attr function gets particle type io attributes. This particle type has position at the center of the grid it belongs to with value grid level (int).
int main(){
...
/* libyt API. */
yt_particle *particle_list;
yt_get_ParticlesPtr( &particle_list );
/* This particle "io" has 4 attributes (position X/Y/Z and level). */
const char *attr_name[] = {"ParPosX", "ParPosY", "ParPosZ", "Level"};
const char *attr_name_alias[] = {"grid_level"};
for ( int v=0; v < 4; v++ ){
particle_list[0].attr_list[v].attr_name = attr_name[v];
if ( v == 3 ){
particle_list[0].attr_list[v].attr_dtype = YT_INT;
particle_list[0].attr_list[v].attr_unit = "";
particle_list[0].attr_list[v].num_attr_name_alias = 1;
particle_list[0].attr_list[v].attr_name_alias = attr_name_alias;
particle_list[0].attr_list[v].attr_display_name = "Level of the Grid";
}
else{
particle_list[0].attr_list[v].attr_dtype = ( typeid(real) == typeid(float) ) ? YT_FLOAT : YT_DOUBLE;
}
}
/* Fill in positions attribute name. */
particle_list[0].coor_x = attr_name[0];
particle_list[0].coor_y = attr_name[1];
particle_list[0].coor_z = attr_name[2];
/* Fill in get attribute function pointer. */
particle_list[0].get_par_attr = par_io_get_par_attr;
}
void par_io_get_par_attr(const int list_len, const long *gid_list, const char *par_type, const char *attribute, yt_array *data_array) {
// loop over gid_list, and fill in particle attribute data inside data_array.
for (int lid = 0; lid < list_len; lid++) {
// =============================================================
// libyt: [Optional] Use libyt look up grid info API
// =============================================================
int Level;
double RightEdge[3], LeftEdge[3];
yt_getGridInfo_Level(gid_list[lid], &Level);
yt_getGridInfo_RightEdge(gid_list[lid], &RightEdge);
yt_getGridInfo_LeftEdge(gid_list[lid], &LeftEdge);
// fill in particle data.
// we can get the length of the array to fill in like this, though this example only has one particle in each grid.
for (int i = 0; i < data_array[lid].data_length; i++) {
// fill in particle data according to the attribute.
if (strcmp(attribute, "ParPosX") == 0) {
((real *) data_array[lid].data_ptr)[0] = 0.5 * (RightEdge[0] + LeftEdge[0]);
} else if (strcmp(attribute, "ParPosY") == 0) {
((real *) data_array[lid].data_ptr)[0] = 0.5 * (RightEdge[1] + LeftEdge[1]);
} else if (strcmp(attribute, "ParPosZ") == 0) {
((real *) data_array[lid].data_ptr)[0] = 0.5 * (RightEdge[2] + LeftEdge[2]);
} else if (strcmp(attribute, "Level") == 0) {
((int *) data_array[lid].data_ptr)[0] = Level;
}
}
}
}