Tissue Forge C++ 0.2.1
Interactive, particle-based physics, chemistry and biology modeling and simulation environment
Loading...
Searching...
No Matches
tfParticle.h
Go to the documentation of this file.
1/*******************************************************************************
2 * This file is part of mdcore.
3 * Coypright (c) 2010 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
4 * Coypright (c) 2017 Andy Somogyi (somogyie at indiana dot edu)
5 * Copyright (c) 2022-2024 T.J. Sego
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ******************************************************************************/
21
26
27#ifndef _MDCORE_INCLUDE_TFPARTICLE_H_
28#define _MDCORE_INCLUDE_TFPARTICLE_H_
29#include "tf_platform.h"
30#include "tf_fptype.h"
31#include <state/tfStateVector.h>
32#include <types/tf_types.h>
33#include "tfSpace_cell.h"
34#include "tfAngle.h"
35#include "tfBond.h"
36#include "tfDihedral.h"
37#include "tfParticleList.h"
38#include "tfParticleTypeList.h"
39#include <set>
40#include <vector>
41
45#define CLUSTER_PARTLIST_INCR 50
46
47
48namespace TissueForge {
49
50
51 namespace rendering {
52 struct Style;
53 }
54
55
56 typedef enum ParticleTypeFlags {
57 PARTICLE_TYPE_NONE = 0,
58 PARTICLE_TYPE_INERTIAL = 1 << 0,
59 PARTICLE_TYPE_DISSAPATIVE = 1 << 1,
60 } ParticleTypeFlags;
61
62 typedef enum ParticleDynamics {
63 PARTICLE_NEWTONIAN = 0,
64 PARTICLE_OVERDAMPED = 1,
65 } ParticleDynamics;
66
67 /* particle flags */
68 typedef enum ParticleFlags {
69 PARTICLE_NONE = 0,
70 PARTICLE_GHOST = 1 << 0,
71 PARTICLE_CLUSTER = 1 << 1,
72 PARTICLE_BOUND = 1 << 2,
73 PARTICLE_FROZEN_X = 1 << 3,
74 PARTICLE_FROZEN_Y = 1 << 4,
75 PARTICLE_FROZEN_Z = 1 << 5,
76 PARTICLE_FROZEN = PARTICLE_FROZEN_X | PARTICLE_FROZEN_Y | PARTICLE_FROZEN_Z,
77 PARTICLE_LARGE = 1 << 6,
78 } ParticleFlags;
79
80
82 // CAPI_DATA(int) particle_err;
83
84 struct Cluster;
85 struct ClusterParticleHandle;
86
101 struct CAPI_EXPORT Particle {
102
111 union {
112 TF_ALIGNED(FPTYPE, 16) f[4];
113 TF_ALIGNED(FVector3, 16) force;
114
115 struct {
116 FPTYPE __dummy0[3];
117 FPTYPE number_density;
118 };
119 };
120
126 union {
127 TF_ALIGNED(FVector3, 16) force_i;
128 };
129
130
132 union {
133 TF_ALIGNED(FPTYPE, 16) v[4];
134 TF_ALIGNED(FVector3, 16) velocity;
135
136 struct {
137 FPTYPE __dummy1[3];
138 FPTYPE inv_number_density;
139 };
140 };
141
142
144 union {
145 TF_ALIGNED(FPTYPE, 16) x[4];
146 TF_ALIGNED(FVector3, 16) position;
147
148 struct {
149 FPTYPE __dummy2[3];
150 uint32_t creation_time;
151 };
152 };
153
154
156 union {
157 TF_ALIGNED(FVector3, 16) persistent_force;
158 };
159
161 FPTYPE imass;
162
164 FPTYPE radius;
165
167 FPTYPE mass;
168
170 FPTYPE q;
171
172 // runge-kutta k intermediates.
173 FVector3 p0;
174 FVector3 v0;
175 FVector3 xk[4];
176 FVector3 vk[4];
177
182 int id, vid;
183
185 int16_t typeId;
186
188 int32_t clusterId;
189
191 uint16_t flags;
192
200
205
209 int32_t *parts;
210
212 uint16_t nr_parts;
213
215 uint16_t size_parts;
216
220 HRESULT addpart(int32_t uid);
221
226 HRESULT removepart(int32_t uid);
227
229 Particle *particle(int i);
230
237
244
248 FVector3 global_position();
249
253 void set_global_position(const FVector3& pos);
254
258 bool verify();
259
260
266 operator Cluster*();
267
268 Particle();
269
273 std::string toString();
274
286 static Particle *fromString(const std::string &str);
287 };
288
293
294 #ifndef NDEBUG
295 #define VERIFY_PARTICLES() Particle_Verify()
296 #else
297 #define VERIFY_PARTICLES()
298 #endif
299
300
313 struct CAPI_EXPORT ParticleHandle {
315 int id;
316
322 Particle *part();
323
329 Particle *get() { return part(); }
330
334 ParticleType *type();
335
336 ParticleHandle() : id(0) {}
337 ParticleHandle(const int &id) : id(id) {}
338
339 virtual std::string str() const;
340
341 virtual ParticleHandle* fission();
342
364 virtual ParticleHandle* split();
365
389 virtual ParticleHandle* split(const FVector3& childDirection);
390
414 virtual ParticleHandle* split(const FPTYPE& childRatio);
415
439 virtual ParticleHandle* split(const std::vector<FPTYPE>& speciesRatios);
440
469 virtual ParticleHandle* split(
470 const FVector3& childDirection,
471 const FPTYPE& childRatio,
472 ParticleType* parentType=NULL,
473 ParticleType* childType=NULL
474 );
475
506 virtual ParticleHandle* split(
507 const FVector3& childDirection,
508 const FPTYPE& childRatio,
509 const std::vector<FPTYPE>& speciesRatios,
510 ParticleType* parentType=NULL,
511 ParticleType* childType=NULL
512 );
513
520
529 FVector3 sphericalPosition(Particle *particle=NULL, FVector3 *origin=NULL);
530
538 FVector3 relativePosition(const FVector3 &origin, const bool &comp_bc=true);
539
545 virtual FMatrix3 virial(FPTYPE *radius=NULL);
546
558
566
573 ParticleList neighbors(const FPTYPE &distance, const std::vector<ParticleType> &types);
574
581
588
594 ParticleList neighbors(const std::vector<ParticleType> &types);
595
602 std::vector<int32_t> neighborIds(const FPTYPE &distance, const TissueForge::ParticleTypeList &types);
603
610 std::vector<int32_t> neighborIds(const FPTYPE &distance, const std::vector<ParticleType> &types);
611
617 std::vector<int32_t> neighborIds(const FPTYPE &distance=-FPTYPE_ONE);
618
624 std::vector<int32_t> neighborIds(const TissueForge::ParticleTypeList &types);
625
631 std::vector<int32_t> neighborIds(const std::vector<ParticleType> &types);
632
637
641 std::vector<int32_t> getBondedNeighborIds();
642
648 FPTYPE distance(ParticleHandle *_other);
649
651 std::vector<struct TissueForge::BondHandle> getBonds();
652
654 std::vector<struct TissueForge::AngleHandle> getAngles();
655
657 std::vector<struct TissueForge::DihedralHandle> getDihedrals();
658
660 FPTYPE getCharge();
661
663 void setCharge(const FPTYPE &charge);
664
666 FPTYPE getMass();
667
669 void setMass(const FPTYPE &mass);
670
672 bool getFrozen();
673
675 void setFrozen(const bool frozen);
676
679
681 void setFrozenX(const bool frozen);
682
685
687 void setFrozenY(const bool frozen);
688
691
693 void setFrozenZ(const bool frozen);
694
697
700
702 FPTYPE getAge();
703
705 FPTYPE getRadius();
706
708 void setRadius(const FPTYPE &radius);
709
711 FPTYPE getVolume();
712
714 std::string getName();
715
717 std::string getName2();
718
720 FVector3 getPosition();
721
723 void setPosition(FVector3 position);
724
726 FVector3 &getVelocity();
727
729 void setVelocity(FVector3 velocity);
730
732 FVector3 getForce();
733
735 FVector3 &getForceInit();
736
738 void setForceInit(FVector3 force);
739
741 int getId();
742
744 int16_t getTypeId();
745
747 int32_t getClusterId();
748
750 uint16_t getFlags();
751
754
759 };
760
768 struct CAPI_EXPORT ParticleType {
769
770 static const int MAX_NAME = 64;
771
773 int16_t id;
774
778 uint32_t type_flags;
779
785
789 FPTYPE mass;
790
791 FPTYPE imass;
792
796 FPTYPE charge;
797
801 FPTYPE radius;
802
807
812
817
825
827 FPTYPE eps, rmin;
828
832 unsigned char dynamics;
833
837 char name[MAX_NAME];
838
839 char name2[MAX_NAME];
840
845
850
855
860
864 HRESULT addpart(int32_t id);
865
869 HRESULT del_part(int32_t id);
870
877
881 static std::set<short int> particleTypeIds();
882
884 bool isCluster();
885
890
902 FVector3 *position=NULL,
903 FVector3 *velocity=NULL,
904 int *clusterId=NULL
905 );
906
916 TissueForge::ParticleHandle *operator()(const std::string &str, int *clusterId=NULL);
917
930 std::vector<int> factory(
931 unsigned int nr_parts=0,
932 std::vector<FVector3> *positions=NULL,
933 std::vector<FVector3> *velocities=NULL,
934 std::vector<int> *clusterIds=NULL
935 );
936
945 ParticleType* newType(const char *_name);
946
948 bool has(const int32_t &pid);
949
951 bool has(ParticleHandle *part);
952
959
963 virtual void on_register() {}
964
971
975 virtual ParticleType *get();
976
977 ParticleType(const bool &noReg=false);
978 virtual ~ParticleType() {}
979
980 virtual std::string str() const;
981
983 FPTYPE getVolume();
984
986 bool getFrozen();
987
989 void setFrozen(const bool &frozen);
990
993
995 void setFrozenX(const bool &frozen);
996
999
1001 void setFrozenY(const bool &frozen);
1002
1005
1007 void setFrozenZ(const bool &frozen);
1008
1011
1014
1016 void setTargetTemperature(const FPTYPE &temperature);
1017
1022
1024 uint16_t getNumParts();
1025
1027 std::vector<int32_t> getPartIds();
1028
1032 std::string toString();
1033
1041 static ParticleType *fromString(const std::string &str);
1042 };
1043
1044 CAPI_FUNC(ParticleType*) Particle_GetType();
1045
1046 CAPI_FUNC(ParticleType*) Cluster_GetType();
1047
1055 struct engine *e,
1056 FPTYPE mass,
1057 FPTYPE charge,
1058 const char *name,
1059 const char *name2
1060 );
1061
1068 ParticleType* ParticleType_New(const char *_name);
1069
1076 CAPI_FUNC(ParticleType*) ParticleType_FindFromName(const char* name);
1077
1083
1084
1085 ParticleHandle* Particle_split(
1086 Particle* self,
1087 const FVector3& childDirection,
1088 const FPTYPE& childRatio,
1089 const std::vector<FPTYPE>* speciesRatios=NULL,
1090 ParticleType* parentType=NULL,
1091 ParticleType* childType=NULL
1092 );
1093
1094 CAPI_FUNC(ParticleHandle*) Particle_New(
1095 ParticleType *type,
1096 FVector3 *positn=NULL,
1097 FVector3 *velocity=NULL,
1098 int *clusterId=NULL
1099 );
1100
1101 std::vector<int> Particles_New(
1102 std::vector<ParticleType*> types,
1103 std::vector<FVector3> *positions=NULL,
1104 std::vector<FVector3> *velocities=NULL,
1105 std::vector<int> *clusterIds=NULL
1106 );
1107
1108 std::vector<int> Particles_New(
1109 ParticleType *type,
1110 unsigned int nr_parts=0,
1111 std::vector<FVector3> *positions=NULL,
1112 std::vector<FVector3> *velocities=NULL,
1113 std::vector<int> *clusterIds=NULL
1114 );
1115
1126
1130 CAPI_DATA(unsigned int) *Particle_Colors;
1131
1132 // Returns 1 if a type has been registered, otherwise 0
1133 CAPI_FUNC(bool) ParticleType_checkRegistered(ParticleType *type);
1134
1143
1144 inline bool operator< (const TissueForge::ParticleHandle& lhs, const TissueForge::ParticleHandle& rhs) { return lhs.id < rhs.id; }
1145 inline bool operator> (const TissueForge::ParticleHandle& lhs, const TissueForge::ParticleHandle& rhs) { return rhs < lhs; }
1146 inline bool operator<=(const TissueForge::ParticleHandle& lhs, const TissueForge::ParticleHandle& rhs) { return !(lhs > rhs); }
1147 inline bool operator>=(const TissueForge::ParticleHandle& lhs, const TissueForge::ParticleHandle& rhs) { return !(lhs < rhs); }
1148 inline bool operator==(const TissueForge::ParticleHandle& lhs, const TissueForge::ParticleHandle& rhs) { return lhs.id == rhs.id; }
1149 inline bool operator!=(const TissueForge::ParticleHandle& lhs, const TissueForge::ParticleHandle& rhs) { return !(lhs == rhs); }
1150
1151 inline bool operator< (const TissueForge::ParticleType& lhs, const TissueForge::ParticleType& rhs) { return lhs.id < rhs.id; }
1152 inline bool operator> (const TissueForge::ParticleType& lhs, const TissueForge::ParticleType& rhs) { return rhs < lhs; }
1153 inline bool operator<=(const TissueForge::ParticleType& lhs, const TissueForge::ParticleType& rhs) { return !(lhs > rhs); }
1154 inline bool operator>=(const TissueForge::ParticleType& lhs, const TissueForge::ParticleType& rhs) { return !(lhs < rhs); }
1155 inline bool operator==(const TissueForge::ParticleType& lhs, const TissueForge::ParticleType& rhs) { return lhs.id == rhs.id; }
1156 inline bool operator!=(const TissueForge::ParticleType& lhs, const TissueForge::ParticleType& rhs) { return !(lhs == rhs); }
1157
1158
1159};
1160
1161
1162inline std::ostream &operator<<(std::ostream& os, const TissueForge::ParticleHandle &p)
1163{
1164 os << p.str().c_str();
1165 return os;
1166}
1167
1168inline std::ostream &operator<<(std::ostream& os, const TissueForge::ParticleType &p)
1169{
1170 os << p.str().c_str();
1171 return os;
1172}
1173
1174#endif // _MDCORE_INCLUDE_TFPARTICLE_H_
Native Tissue Forge type definitions.
Definition tfMatrix.h:33
Include Python header, disable linking to pythonX_d.lib on Windows in debug mode.
Definition tfAngleConfig.h:26
unsigned int * Particle_Colors
Definition tfParticle.h:1130
Particle * Particle_Get(ParticleHandle *pypart)
ParticleType * ParticleType_ForEngine(struct engine *e, FPTYPE mass, FPTYPE charge, const char *name, const char *name2)
ParticleType * ParticleType_FindFromName(const char *name)
Get a registered particle type by type name.
HRESULT Particle_Verify()
HRESULT Particle_Become(Particle *part, ParticleType *type)
HRESULT _Particle_init()
ParticleType * ParticleType_New(const char *_name)
The cluster analogue to :class:Particle.
Definition tfCluster.h:40
The cluster analogue to :class:ParticleHandle.
Definition tfCluster.h:102
The cluster analogue to :class:ParticleType.
Definition tfCluster.h:48
A handle to a particle.
Definition tfParticle.h:313
std::vector< int32_t > neighborIds(const std::vector< ParticleType > &types)
Gets a list of nearby particles ids within the global cutoff distance.
void setMass(const FPTYPE &mass)
std::vector< struct TissueForge::AngleHandle > getAngles()
virtual ParticleHandle * split(const FPTYPE &childRatio)
Splits a single particle into two with sizes according to a given ratio.
ParticleList neighbors(const FPTYPE &distance, const std::vector< ParticleType > &types)
Gets a list of nearby particles.
virtual ParticleHandle * split(const FVector3 &childDirection)
Splits a single particle into two along a given direction.
virtual ParticleHandle * split()
Splits a single particle into two.
Particle * part()
Gets the actual particle of this handle.
Definition tfEngine.h:1414
std::vector< int32_t > neighborIds(const FPTYPE &distance=-FPTYPE_ONE)
Gets a list of nearby particles ids of all types.
virtual ParticleHandle * split(const FVector3 &childDirection, const FPTYPE &childRatio, const std::vector< FPTYPE > &speciesRatios, ParticleType *parentType=NULL, ParticleType *childType=NULL)
Splits a single particle into two along a given direction, with sizes according to a given ratio,...
ParticleList neighbors(const FPTYPE &distance, const TissueForge::ParticleTypeList &types)
Gets a list of nearby particles.
std::vector< struct TissueForge::BondHandle > getBonds()
ParticleList neighbors(const std::vector< ParticleType > &types)
Gets a list of nearby particles within the global cutoff distance.
void setFrozenX(const bool frozen)
void setForceInit(FVector3 force)
FVector3 relativePosition(const FVector3 &origin, const bool &comp_bc=1)
Computes the relative position with respect to an origin while optionally account for boundary condit...
rendering::Style * getStyle()
std::vector< struct TissueForge::DihedralHandle > getDihedrals()
ParticleList neighbors(const FPTYPE &distance)
Gets a list of nearby particles of all types.
void setRadius(const FPTYPE &radius)
void setFrozenY(const bool frozen)
void setCharge(const FPTYPE &charge)
HRESULT destroy()
Destroys the particle and removes it from inventory.
void setFrozenZ(const bool frozen)
std::vector< int32_t > neighborIds(const FPTYPE &distance, const std::vector< ParticleType > &types)
Gets a list of nearby particles ids.
void setFrozen(const bool frozen)
int id
Definition tfParticle.h:315
ParticleList neighbors(const TissueForge::ParticleTypeList &types)
Gets a list of nearby particles within the global cutoff distance.
void setPosition(FVector3 position)
virtual FMatrix3 virial(FPTYPE *radius=NULL)
Computes the virial tensor. Optionally pass a distance to include a neighborhood.
virtual ParticleHandle * split(const FVector3 &childDirection, const FPTYPE &childRatio, ParticleType *parentType=NULL, ParticleType *childType=NULL)
Splits a single particle into two along a given direction, with sizes according to a given ratio,...
virtual ParticleHandle * split(const std::vector< FPTYPE > &speciesRatios)
Splits a single particle into two and allocates species according to given ratios.
std::vector< int32_t > neighborIds(const TissueForge::ParticleTypeList &types)
Gets a list of nearby particles ids within the global cutoff distance.
std::vector< int32_t > getBondedNeighborIds()
Gets a list of all bonded neighbor ids.
Particle * get()
Gets the actual particle of this handle.
Definition tfParticle.h:329
void setStyle(rendering::Style *style)
FPTYPE distance(ParticleHandle *_other)
Calculates the distance to another particle.
ParticleType * type()
Gets the particle type of this handle.
Definition tfEngine.h:1418
ParticleList getBondedNeighbors()
Gets a list of all bonded neighbors.
HRESULT become(ParticleType *type)
Dynamically changes the type of an object. We can change the type of a ParticleType-derived object to...
void setVelocity(FVector3 velocity)
std::vector< int32_t > neighborIds(const FPTYPE &distance, const TissueForge::ParticleTypeList &types)
Gets a list of nearby particles ids.
state::StateVector * getSpecies()
FVector3 sphericalPosition(Particle *particle=NULL, FVector3 *origin=NULL)
Calculates the particle's coordinates in spherical coordinates.
Definition tfParticle.h:101
void set_global_position(const FVector3 &pos)
Set the global position.
Definition tfEngine.h:1409
int id
Definition tfParticle.h:182
struct state::StateVector * state_vector
Definition tfParticle.h:243
Particle * particle(int i)
Definition tfEngine.h:1399
int16_t typeId
Definition tfParticle.h:185
int32_t * parts
Definition tfParticle.h:209
FPTYPE q
Definition tfParticle.h:170
std::string toString()
Get a JSON string representation.
HRESULT addpart(int32_t uid)
static Particle * fromString(const std::string &str)
Create from a JSON string representation.
int32_t clusterId
Definition tfParticle.h:188
uint16_t size_parts
Definition tfParticle.h:215
FPTYPE radius
Definition tfParticle.h:164
struct ParticleHandle * _handle
Definition tfParticle.h:199
FPTYPE imass
Definition tfParticle.h:161
FVector3 global_position()
Get the global position.
Definition tfEngine.h:1403
uint16_t flags
Definition tfParticle.h:191
struct ParticleHandle * handle()
Get a handle for this particle.
FPTYPE mass
Definition tfParticle.h:167
uint16_t nr_parts
Definition tfParticle.h:212
rendering::Style * style
Definition tfParticle.h:236
HRESULT removepart(int32_t uid)
A special list with convenience methods for working with sets of particles.
Definition tfParticleList.h:52
Structure containing information on each particle type.
Definition tfParticle.h:768
ParticleType * newType(const char *_name)
Particle type constructor.
bool has(ParticleHandle *part)
TissueForge::ParticleHandle * operator()(const std::string &str, int *clusterId=NULL)
Particle constructor.
virtual HRESULT registerType()
Registers a type with the engine.
uint32_t type_flags
Definition tfParticle.h:778
FPTYPE radius
Default radius of particles.
Definition tfParticle.h:801
virtual ParticleType * get()
Get the type engine instance.
std::string toString()
Get a JSON string representation.
TissueForge::ParticleHandle * operator()(FVector3 *position=NULL, FVector3 *velocity=NULL, int *clusterId=NULL)
Particle constructor.
rendering::Style * style
style pointer, optional.
Definition tfParticle.h:854
void setFrozenZ(const bool &frozen)
TissueForge::Particle * particle(int i)
get the i'th particle that's a member of this type.
Definition tfEngine.h:1429
std::vector< int > factory(unsigned int nr_parts=0, std::vector< FVector3 > *positions=NULL, std::vector< FVector3 > *velocities=NULL, std::vector< int > *clusterIds=NULL)
Particle factory constructor, for making lots of particles quickly.
FPTYPE kinetic_energy
Kinetic energy of all particles of this type.
Definition tfParticle.h:806
FPTYPE eps
Definition tfParticle.h:827
void setTargetTemperature(const FPTYPE &temperature)
FPTYPE target_energy
Target energy of all particles of this type.
Definition tfParticle.h:816
FPTYPE charge
Default charge of particles.
Definition tfParticle.h:796
void setFrozen(const bool &frozen)
TissueForge::ParticleList parts
list of particles that belong to this type.
Definition tfParticle.h:844
std::vector< int32_t > getPartIds()
TissueForge::ParticleList & items()
Get all particles of this type.
bool isRegistered()
Tests whether this type is registered.
FPTYPE minimum_radius
Default minimum radius of this type.
Definition tfParticle.h:824
virtual void on_register()
A callback for when a type is registered.
Definition tfParticle.h:963
void setFrozenY(const bool &frozen)
void setFrozenX(const bool &frozen)
int16_t id
Definition tfParticle.h:773
uint16_t particle_flags
Definition tfParticle.h:784
HRESULT del_part(int32_t id)
char name[MAX_NAME]
Name of this particle type.
Definition tfParticle.h:837
struct state::SpeciesList * species
optional pointer to species list. This is the metadata for the species
Definition tfParticle.h:859
static std::set< short int > particleTypeIds()
Get all current particle type ids, excluding clusters.
static ParticleType * fromString(const std::string &str)
Create from a JSON string representation.
FPTYPE potential_energy
Potential energy of all particles of this type.
Definition tfParticle.h:811
unsigned char dynamics
Default dynamics of particles of this type.
Definition tfParticle.h:832
bool has(const int32_t &pid)
FPTYPE mass
Default mass of particles.
Definition tfParticle.h:789
TissueForge::ParticleTypeList types
list of particle types that belong to this type.
Definition tfParticle.h:849
HRESULT addpart(int32_t id)
A special list with convenience methods for working with sets of particle types.
Definition tfParticleTypeList.h:41
Definition tfEngine.h:164
The Tissue Forge style type.
Definition tfStyle.h:46
Definition tfSpeciesList.h:37
A state vector of an object.
Definition tfStateVector.h:50
int32_t HRESULT
Definition tf_port.h:255