tmp<fvVectorMatrix> surfaceShearForce::correct(volVectorField& U) { // local reference to film model const kinematicSingleLayer& film = static_cast<const kinematicSingleLayer&>(owner_); // local references to film fields const volScalarField& mu = film.mu(); const volVectorField& Uw = film.Uw(); const volScalarField& delta = film.delta(); const volVectorField& Up = film.UPrimary(); // film surface linear coeff to apply to velocity tmp<volScalarField> tCs; typedef compressible::turbulenceModel turbModel; if (film.primaryMesh().foundObject<turbModel>("turbulenceProperties")) { // local reference to turbulence model const turbModel& turb = film.primaryMesh().lookupObject<turbModel>("turbulenceProperties"); // calculate and store the stress on the primary region const volSymmTensorField primaryReff(turb.devRhoReff()); // create stress field on film // - note boundary condition types (mapped) // - to map, the field name must be the same as the field on the // primary region volSymmTensorField Reff ( IOobject ( primaryReff.name(), film.regionMesh().time().timeName(), film.regionMesh(), IOobject::NO_READ, IOobject::NO_WRITE ), film.regionMesh(), dimensionedSymmTensor ( "zero", primaryReff.dimensions(), symmTensor::zero ), film.mappedFieldAndInternalPatchTypes<symmTensor>() ); // map stress from primary region to film region Reff.correctBoundaryConditions(); dimensionedScalar U0("SMALL", U.dimensions(), SMALL); tCs = Cf_*mag(-film.nHat() & Reff)/(mag(Up - U) + U0); } else { // laminar case - employ simple coeff-based model const volScalarField& rho = film.rho(); tCs = Cf_*rho*mag(Up - U); } dimensionedScalar d0("SMALL", delta.dimensions(), SMALL); // linear coeffs to apply to velocity const volScalarField& Cs = tCs(); volScalarField Cw("Cw", mu/(0.3333*(delta + d0))); Cw.min(1.0e+06); return ( - fvm::Sp(Cs, U) + Cs*Up // surface contribution - fvm::Sp(Cw, U) + Cw*Uw // wall contribution ); }
//------------------------------------------------------------------------------ //! void adjustLimb( Skeleton::Instance& skelInst, const Puppeteer::PositionalConstraint& constraint, const Vec3f& dRoot ) { Skeleton* skeleton = skelInst.skeleton(); int cID = constraint.id(); const Skeleton::Limb& limb = skeleton->limbFromBone( cID ); int sID = limb.boneID(); int eID = limb.endEffectorID(); // 1. Compute mid angle. float b1Len = skeleton->bone( sID ).length(); float b2Len = skeleton->bone( eID ).length(); // Current angle. Vec3f cdir = constraint.currentPos()-skelInst.globalPosition(sID); float clenSqr = cdir.sqrLength(); float ccosAngle = (b1Len*b1Len + b2Len*b2Len - clenSqr) / (2*b1Len*b2Len); ccosAngle = CGM::clamp( ccosAngle, -1.0f, 1.0f ); float cangle = CGM::acos( ccosAngle ); // New angle. Vec3f dir = constraint.endPos()-(skelInst.globalPosition(sID)+dRoot); float lenSqr = dir.sqrLength(); float cosAngle = (b1Len*b1Len + b2Len*b2Len - lenSqr) / (2*b1Len*b2Len); cosAngle = CGM::clamp( cosAngle, -1.0f, 1.0f ); float angle = CGM::acos( cosAngle ); float diffAngle = cangle-angle; Quatf orient; switch( skeleton->bone( eID ).dof() ) { case Skeleton::RX: orient = Quatf::eulerX( diffAngle ); break; case Skeleton::RY: orient = Quatf::eulerY( diffAngle ); break; case Skeleton::RZ: orient = Quatf::eulerZ( diffAngle ); break; default: orient = Quatf::eulerX( diffAngle ); } orient = orient * skelInst.localOrientation( eID ); // 2. Compute start angle. // 2.1 target position in local space of first limb bone. Vec3f target = skelInst.globalReferential(sID).globalToLocal() * (constraint.endPos()-dRoot); // 2.2 Compute new current end effector position in limb space. Vec3f localPos = skelInst.localReferential(eID).position(); Vec3f curPos = Reff( orient, localPos ).toMatrix() * skeleton->bone(eID).endPoint(); // 2.3 Compute rotation quaternion. Quatf rot = Quatf::twoVecs( curPos, target ); rot = rot * skelInst.localOrientation(sID); // 3. Blend with slerp/nlerp. //skelInst.localOrientationNoUpdate( sID, skelInst.localOrientation(sID).slerp( rot, constraint.weight() ) ); //skelInst.localOrientationNoUpdate( eID, skelInst.localOrientation(eID).slerp( orient, constraint.weight() ) ); skelInst.localOrientationNoUpdate( sID, skelInst.localOrientation(sID).nlerp( rot, constraint.weight() ) ); skelInst.localOrientationNoUpdate( eID, skelInst.localOrientation(eID).nlerp( orient, constraint.weight() ) ); }