BinKinematics_SphereWlin class
Contents
Description
This is a sub-class of the BinKinematics class for the implementation of the Sphere-Wall Line binary kinematics for particle-wall interactions of types Particle Sphere and Wall Line.
classdef BinKinematics_SphereWlin < BinKinematics
Constructor method
methods
function this = BinKinematics_SphereWlin()
this = this@BinKinematics(BinKinematics.PARTICLE_WALL,BinKinematics.SPHERE_WALL_LINE);
end
end
Public methods: implementation of super-class declarations
methods
%------------------------------------------------------------------
function setEffParams(~,int)
p = int.elem1; w = int.elem2;
mp = p.material; mw = w.material;
% Assumption: effective radius and mass consider particle only
int.eff_radius = p.radius;
int.eff_mass = p.mass;
% Wall with no material
% Assumption: effective and average properties are the particle values
if (isempty(mw))
if (~isempty(mp.young) && ~isempty(mp.poisson))
int.eff_young = mp.young / (1 - mp.poisson^2);
if (~isempty(mp.young0))
int.eff_young0 = mp.young0 / (1 - mp.poisson^2);
end
end
if (~isempty(mp.shear) && ~isempty(mp.poisson))
int.eff_shear = mp.shear / (2 - mp.poisson^2);
end
if (~isempty(mp.poisson))
int.avg_poisson = mp.poisson;
end
if (~isempty(mp.conduct))
int.eff_conduct = mp.conduct/2;
int.avg_conduct = mp.conduct;
end
% Wall with material
else
if (~isempty(mp.young) && ~isempty(mp.poisson) && ~isempty(mw.young) && ~isempty(mw.poisson))
int.eff_young = 1 / ((1-mp.poisson^2)/mp.young + (1-mw.poisson^2)/mw.young);
if (~isempty(mp.young0) && ~isempty(mw.young0))
int.eff_young0 = 1 / ((1-mp.poisson^2)/mp.young0 + (1-mw.poisson^2)/mw.young0);
end
end
if (~isempty(mp.shear) && ~isempty(mp.poisson) && ~isempty(mw.shear) && ~isempty(mw.poisson))
int.eff_shear = 1 / ((2-mp.poisson^2)/mp.shear + (2-mw.poisson^2)/mw.shear);
end
if (~isempty(mp.poisson) && ~isempty(mw.poisson))
int.avg_poisson = (mp.poisson + mw.poisson) / 2;
end
if (~isempty(mp.conduct) && ~isempty(mw.conduct))
int.eff_conduct = mp.conduct * mw.conduct / (mp.conduct + mw.conduct);
int.avg_conduct = mp.conduct; % assumption: average conductivity considers particle only
end
end
end
%------------------------------------------------------------------
function this = setRelPos(this,p,w)
% Needed properties
P = p.coord;
A = w.coord_ini;
B = w.coord_end;
M = B - A;
% Running parameter at the orthogonal intersection
t = dot(M,P-A)/w.len^2;
% Normal direction from particle to wall
if (t <= 0)
this.dir = A-P;
elseif (t >= 1)
this.dir = B-P;
else
this.dir = (A + t * M) - P;
end
% Distance between particle surface and line segment
this.dist = norm(this.dir);
this.distc = this.dist;
this.separ = this.dist - p.radius;
end
%------------------------------------------------------------------
function this = setOverlaps(this,int,dt)
p = int.elem1; w = int.elem2;
% Normal overlap and unit vector
% Assumption: the ends of the wall are treated as a flat surface
this.ovlp_n = -this.separ;
this.dir_n = this.dir / norm(this.dir);
% Positions of contact point
% Assumption: discount the full overlap from particle
cp = (p.radius - this.ovlp_n) * this.dir_n;
cw = (p.coord+cp) - (w.coord_ini+w.coord_end)/2;
% Particle velocity at contact point (3D due to cross-product)
wp = cross([0;0;p.veloc_rot],[cp(1);cp(2);0]);
vcp = p.veloc_trl + wp(1:2);
% Wall velocity at contact point (3D due to cross-product)
ww = cross([0;0;w.veloc_rot],[cw(1);cw(2);0]);
vcw = w.veloc_trl + ww(1:2);
% Relative velocities
% Assumption: rotation and angular velocities consider the particle only
this.vel_trl = vcp - vcw;
this.vel_rot = wp(1:2); % particle only
this.vel_ang = p.veloc_rot; % particle only
% Normal overlap rate of change
this.vel_n = dot(this.vel_trl,this.dir_n);
% Tangential relative velocity
vt = this.vel_trl - this.vel_n * this.dir_n;
% Tangential unit vector
if (any(vt))
this.dir_t = vt / norm(vt);
else
this.dir_t = [0;0];
end
% Tangential overlap rate of change
this.vel_t = dot(this.vel_trl,this.dir_t);
% Tangential overlap
if (isempty(this.ovlp_t))
this.ovlp_t = this.vel_t * dt;
else
this.ovlp_t = this.ovlp_t + this.vel_t * dt;
end
end
%------------------------------------------------------------------
function this = setContactArea(this,int)
% Needed properties
r = int.elem1.radius;
d = this.dist;
% Contact radius
this.contact_radius = sqrt(r^2-d^2);
% Contact correction
if (~isempty(int.corarea))
% Adjusted radius
int.corarea.fixRadius(int);
% Adjusted distance consistent with adjusted radius
this.distc = sqrt(r^2-this.contact_radius^2);
end
end
%------------------------------------------------------------------
function this = setVoronoiEdge(this,~,int)
% Assumption: same as the particle diameter
this.vedge = 2*int.elem1.radius;
end
%------------------------------------------------------------------
function addContactForceNormalToParticles(~,int)
int.elem1.force = int.elem1.force + int.cforcen.total_force;
end
%------------------------------------------------------------------
function addContactForceTangentToParticles(~,int)
int.elem1.force = int.elem1.force + int.cforcet.total_force;
end
%------------------------------------------------------------------
function addContactTorqueTangentToParticles(this,int)
% Lever arm
% Assumption: half of the overlap
l = (int.elem1.radius-this.ovlp_n/2) * this.dir_n;
% Torque from tangential contact force (3D due to cross-product)
f = int.cforcet.total_force;
torque = cross([l(1);l(2);0],[f(1);f(2);0]);
% Add torque from tangential contact force to particle
int.elem1.torque = int.elem1.torque + torque(3);
end
%------------------------------------------------------------------
function addRollResistTorqueToParticles(~,int)
int.elem1.torque = int.elem1.torque + int.rollres.torque;
end
%------------------------------------------------------------------
function addDirectConductionToParticles(~,int)
int.elem1.heat_rate = int.elem1.heat_rate + int.dconduc.total_hrate;
end
%------------------------------------------------------------------
function addIndirectConductionToParticles(~,int)
int.elem1.heat_rate = int.elem1.heat_rate + int.iconduc.total_hrate;
end
end
end