yt_get_ParticlesPtr
– Set Particle Information¶
yt_get_ParticlesPtr
¶
int yt_get_ParticlesPtr( yt_particle **particle_list );
Usage: Get the
yt_particle
array pointer wherelibyt
access 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_SUCCESS
orYT_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.
libyt
only copies the pointer frompar_type_list
’s data memberpar_type
to this variable and does not make a hard copy. You don’t need to assign it again.
The lifetime ofpar_type
should cover in situ analysis process.libyt
only borrows this pointer and does not make a hard copy.int num_attr
(set bylibyt
)Usage: Number of attributes this particle type has.
libyt
will assign your inputpar_type_list
’s data membernum_attr
to this variable. You may skip this.
yt_attribute* attr_list
(initialized bylibyt
)Usage: Attribute list of this particle. This is a
yt_attribute
array with lengthnum_attr
.Data member in
yt_attribute
:const char* attr_name
(Default=NULL
)Usage: Attribute name.
The lifetime ofattr_name
should cover in situ analysis process.libyt
only 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
yt
unit system.
The lifetime ofattr_unit
should 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 ofattr_name_alias
should 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_name
instead.
The lifetime ofattr_display_name
should 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 ofcoor_x
,coor_y
,coor_z
should cover the in situ analysis process.libyt
only 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.
libyt
borrows 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_name
is already inside your frontend. If you are adding a totally new particle attribute, do add them.libyt
will 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_array
array 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;
}
}
}
}