Particle class
Contents
Description
This is a handle heterogeneous super-class for the definition of particles.
In DEM, particles are assumed to be soft, so that contact forces and heat exchange are originated by overlaps. Furthermore, their shapes are assumed to be preserved after collisions.
This super-class defines abstract methods that must be implemented in the derived sub-classes:
- Particle_Sphere (default)
- Particle_Cylinder
classdef Particle < handle & matlab.mixin.Heterogeneous
Constant values
properties (Constant = true, Access = public) % Types of particle SPHERE = uint8(1); CYLINDER = uint8(2); end
Public properties
properties (SetAccess = public, GetAccess = public) % Identification type uint8 = uint8.empty; % flag for type of particle id uint32 = uint32.empty; % identification number % Geometric properties char_len double = double.empty; % characteristic length surface double = double.empty; % surface area cross double = double.empty; % in-plane cross-sectional area volume double = double.empty; % volume minertia double = double.empty; % moment of inertia % Physical properties material Material = Material.empty; % handle to object of Material_Solid subclass mass double = double.empty; % mass (density * volume) weight double = double.empty; % weight vector (mass * gravity) tinertia double = double.empty; % thermal inertia (mass * heat_capacity) conv_coeff double = double.empty; % convection coefficient % Particle-fluid interaction nusselt % handle to object of Nusselt class % Neighbors Interactions % Attention: These properties may contain references to deleted particles interacts Interact = Interact.empty; % handles to objects of Interact class neigh_p Particle = Particle.empty; % handles to objects of Particle class of neighbour particles neigh_w Wall = Wall.empty; % handles to objects of Wall class of neighbour walls neigh_pid uint32 = uint32.empty; % vector of neighbour particles IDs (int is faster to search than obj) neigh_wid uint32 = uint32.empty; % vector of neighbour walls IDs (int is faster to search than obj) verlet_p Particle = Particle.empty; % handles to objects of Particle class in the verlet list verlet_w Wall = Wall.empty; % handles to objects of Wall class in the verlet list % Porosity data porosity double = double.empty; % average porosity (void ratio) around particle por_freq double = double.empty; % average porosity update frequency (in steps) (double to accept NaN) % Behavior flags free_trl logical = logical.empty; % flag for translational free particle free_rot logical = logical.empty; % flag for rotational free particle free_therm logical = logical.empty; % flag for thermally free particle % Prescribed conditions (handles to objects of Condition class) pc_force Condition = Condition.empty; pc_torque Condition = Condition.empty; pc_heatflux Condition = Condition.empty; pc_heatrate Condition = Condition.empty; % Fixed conditions (handles to objects of Condition class) fc_translation Condition = Condition.empty; fc_rotation Condition = Condition.empty; fc_temperature Condition = Condition.empty; % Total forcing terms force double = double.empty; torque double = double.empty; heat_rate double = double.empty; % Current mechanical state coord double = double.empty; % coordinates of centroid orient double = double.empty; % orientation angle veloc_trl double = double.empty; % translational velocity veloc_rot double = double.empty; % rotational velocity accel_trl double = double.empty; % translational acceleration accel_rot double = double.empty; % rotational acceleration % Current thermal state temperature double = double.empty; % temperature temp_change double = double.empty; % temperature rate of change end
Constructor method
methods function this = Particle(type) if (nargin > 0) this.type = type; end end end
Default sub-class definition
methods (Static, Access = protected) function defaultObject = getDefaultScalarElement defaultObject = Particle_Sphere; end end
Abstract methods: implemented in derived sub-classes
methods (Abstract) %------------------------------------------------------------------ setDefaultProps(this); %------------------------------------------------------------------ setCharLen(this); %------------------------------------------------------------------ setSurface(this); %------------------------------------------------------------------ setCrossSec(this); %------------------------------------------------------------------ setVolume(this); %------------------------------------------------------------------ setMInertia(this); %------------------------------------------------------------------ setLocalPorosity(this,por); %------------------------------------------------------------------ [x1,y1,x2,y2] = getBBoxLimits(this); end
Public methods
methods %------------------------------------------------------------------ function setMass(this) this.mass = this.volume * this.material.density; end %------------------------------------------------------------------ function setWeight(this,g) this.weight = this.mass * g; end %------------------------------------------------------------------ function setTInertia(this) this.tinertia = this.mass * this.material.hcapacity; end %------------------------------------------------------------------ function setConvCoeff(this,drv) if (~isempty(this.nusselt)) Nu = this.nusselt.getValue(this,drv); this.conv_coeff = Nu * drv.fluid.conduct / this.char_len; end end %------------------------------------------------------------------ function resetForcingTerms(this) this.force = [0;0]; this.torque = 0; this.heat_rate = 0; end %------------------------------------------------------------------ function addWeight(this) if (~isempty(this.weight)) this.force = this.force + this.weight; end end %------------------------------------------------------------------ function addGblDampTransl(this,damp_coeff) this.force = this.force - damp_coeff * this.veloc_trl; end %------------------------------------------------------------------ function addGblDampRot(this,damp_coeff) this.torque = this.torque - damp_coeff * this.veloc_rot; end %------------------------------------------------------------------ function addPCForce(this,time) for i = 1:length(this.pc_force) if (this.pc_force(i).isActive(time)) this.force = this.force + this.pc_force(i).getValue(time); end end end %------------------------------------------------------------------ function addPCTorque(this,time) for i = 1:length(this.pc_torque) if (this.pc_torque(i).isActive(time)) this.torque = this.torque + this.pc_torque(i).getValue(time); end end end %------------------------------------------------------------------ function addPCHeatFlux(this,time) for i = 1:length(this.pc_heatflux) if (this.pc_heatflux(i).isActive(time)) hr = this.pc_heatflux(i).getValue(time) * this.surface; this.heat_rate = this.heat_rate + hr; end end end %------------------------------------------------------------------ function addPCHeatRate(this,time) for i = 1:length(this.pc_heatrate) if (this.pc_heatrate(i).isActive(time)) this.heat_rate = this.heat_rate + this.pc_heatrate(i).getValue(time); end end end %------------------------------------------------------------------ function addConvection(this,drv) if (~isempty(this.conv_coeff)) this.heat_rate = this.heat_rate + this.conv_coeff * this.surface * (drv.fluid_temp-this.temperature); end end %------------------------------------------------------------------ function setFixedMech(this,time) this.free_trl = true; this.free_rot = true; for i = 1:length(this.fc_translation) if (this.fc_translation(i).isActive(time)) this.free_trl = false; break; end end for i = 1:length(this.fc_rotation) if (this.fc_rotation(i).isActive(time)) this.free_rot = false; break; end end end %------------------------------------------------------------------ function setFixedThermal(this,time) this.free_therm = true; for i = 1:length(this.fc_temperature) if (this.fc_temperature(i).isActive(time)) this.free_therm = false; return; end end end %------------------------------------------------------------------ function setFCTranslation(this,time,dt) if (this.free_trl) return; end v = [0;0]; for i = 1:length(this.fc_translation) if (this.fc_translation(i).isActive(time)) v = v + this.fc_translation(i).getValue(time); end end this.accel_trl = (v-this.veloc_trl) / dt; this.veloc_trl = v; this.coord = this.coord + v * dt; end %------------------------------------------------------------------ function setFCRotation(this,time,dt) if (this.free_rot) return; end w = 0; for i = 1:length(this.fc_rotation) if (this.fc_rotation(i).isActive(time)) w = w + this.fc_rotation(i).getValue(time); end end this.accel_rot = (w-this.veloc_rot) / dt; this.veloc_rot = w; this.orient = this.orient + w * dt; end %------------------------------------------------------------------ function setFCTemperature(this,time) if (this.free_therm) return; end for i = 1:length(this.fc_temperature) if (this.fc_temperature(i).isActive(time)) this.temperature = this.fc_temperature(i).getValue(time); end end end %------------------------------------------------------------------ function setAccelTrl(this) this.accel_trl = this.force / this.mass; end %------------------------------------------------------------------ function setAccelRot(this) this.accel_rot = this.torque / this.minertia; end %------------------------------------------------------------------ function setTempChange(this) this.temp_change = this.heat_rate / this.tinertia; end end
end