bool Foam::molecule::move ( moleculeCloud& cloud, trackingData& td, const scalar trackTime ) { td.switchProcessor = false; td.keepParticle = true; const constantProperties& constProps(cloud.constProps(id_)); if (td.part() == 0) { // First leapfrog velocity adjust part, required before tracking+force // part v_ += 0.5*trackTime*a_; pi_ += 0.5*trackTime*tau_; } else if (td.part() == 1) { // Leapfrog tracking part while (td.keepParticle && !td.switchProcessor && stepFraction() < 1) { const scalar f = 1 - stepFraction(); trackToAndHitFace(f*trackTime*v_, f, cloud, td); } } else if (td.part() == 2) { // Leapfrog orientation adjustment, carried out before force calculation // but after tracking stage, i.e. rotation carried once linear motion // complete. if (!constProps.pointMolecule()) { const diagTensor& momentOfInertia(constProps.momentOfInertia()); tensor R; if (!constProps.linearMolecule()) { R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx()); pi_ = pi_ & R; Q_ = Q_ & R; } R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy()); pi_ = pi_ & R; Q_ = Q_ & R; R = rotationTensorZ(trackTime*pi_.z()/momentOfInertia.zz()); pi_ = pi_ & R; Q_ = Q_ & R; R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy()); pi_ = pi_ & R; Q_ = Q_ & R; if (!constProps.linearMolecule()) { R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx()); pi_ = pi_ & R; Q_ = Q_ & R; } } setSitePositions(constProps); } else if (td.part() == 3) { // Second leapfrog velocity adjust part, required after tracking+force // part scalar m = constProps.mass(); a_ = Zero; tau_ = Zero; forAll(siteForces_, s) { const vector& f = siteForces_[s]; a_ += f/m; tau_ += (constProps.siteReferencePositions()[s] ^ (Q_.T() & f)); } v_ += 0.5*trackTime*a_; pi_ += 0.5*trackTime*tau_; if (constProps.pointMolecule()) { tau_ = Zero; pi_ = Zero; } if (constProps.linearMolecule()) { tau_.x() = 0.0; pi_.x() = 0.0; } }
bool Foam::molecule::move(molecule::trackingData& td, const scalar trackTime) { td.switchProcessor = false; td.keepParticle = true; const constantProperties& constProps(td.cloud().constProps(id_)); if (td.part() == 0) { // First leapfrog velocity adjust part, required before tracking+force // part v_ += 0.5*trackTime*a_; pi_ += 0.5*trackTime*tau_; } else if (td.part() == 1) { // Leapfrog tracking part scalar tEnd = (1.0 - stepFraction())*trackTime; scalar dtMax = tEnd; while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL) { // set the lagrangian time-step scalar dt = min(dtMax, tEnd); dt *= trackToFace(position() + dt*v_, td); tEnd -= dt; stepFraction() = 1.0 - tEnd/trackTime; } } else if (td.part() == 2) { // Leapfrog orientation adjustment, carried out before force calculation // but after tracking stage, i.e. rotation carried once linear motion // complete. if (!constProps.pointMolecule()) { const diagTensor& momentOfInertia(constProps.momentOfInertia()); tensor R; if (!constProps.linearMolecule()) { R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx()); pi_ = pi_ & R; Q_ = Q_ & R; } R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy()); pi_ = pi_ & R; Q_ = Q_ & R; R = rotationTensorZ(trackTime*pi_.z()/momentOfInertia.zz()); pi_ = pi_ & R; Q_ = Q_ & R; R = rotationTensorY(0.5*trackTime*pi_.y()/momentOfInertia.yy()); pi_ = pi_ & R; Q_ = Q_ & R; if (!constProps.linearMolecule()) { R = rotationTensorX(0.5*trackTime*pi_.x()/momentOfInertia.xx()); pi_ = pi_ & R; Q_ = Q_ & R; } } setSitePositions(constProps); } else if (td.part() == 3) { // Second leapfrog velocity adjust part, required after tracking+force // part scalar m = constProps.mass(); a_ = vector::zero; tau_ = vector::zero; forAll(siteForces_, s) { const vector& f = siteForces_[s]; a_ += f/m; tau_ += (constProps.siteReferencePositions()[s] ^ (Q_.T() & f)); } v_ += 0.5*trackTime*a_; pi_ += 0.5*trackTime*tau_; if (constProps.pointMolecule()) { tau_ = vector::zero; pi_ = vector::zero; } if (constProps.linearMolecule()) { tau_.x() = 0.0; pi_.x() = 0.0; } }