void Foam::pointToPointPlanarInterpolation::calcWeights ( const pointField& sourcePoints, const pointField& destPoints ) { tmp<vectorField> tlocalVertices ( referenceCS_.localPosition(sourcePoints) ); vectorField& localVertices = tlocalVertices(); const boundBox bb(localVertices, true); const point bbMid(bb.midpoint()); if (debug) { Info<< "pointToPointPlanarInterpolation::readData :" << " Perturbing points with " << perturb_ << " fraction of a random position inside " << bb << " to break any ties on regular meshes." << nl << endl; } Random rndGen(123456); forAll(localVertices, i) { localVertices[i] += perturb_ *(rndGen.position(bb.min(), bb.max())-bbMid); }
Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::energyRatio ( scalar ChiA, scalar ChiB ) { CloudType& cloud(this->owner()); Random& rndGen(cloud.rndGen()); scalar ChiAMinusOne = ChiA - 1; scalar ChiBMinusOne = ChiB - 1; if (ChiAMinusOne < SMALL && ChiBMinusOne < SMALL) { return rndGen.scalar01(); } scalar energyRatio; scalar P; do { P = 0; energyRatio = rndGen.scalar01(); if (ChiAMinusOne < SMALL) { P = 1.0 - pow(energyRatio, ChiB); } else if (ChiBMinusOne < SMALL) { P = 1.0 - pow(energyRatio, ChiA); } else { P = pow ( (ChiAMinusOne + ChiBMinusOne)*energyRatio/ChiAMinusOne, ChiAMinusOne ) *pow ( (ChiAMinusOne + ChiBMinusOne)*(1 - energyRatio) /ChiBMinusOne, ChiBMinusOne ); } } while (P < rndGen.scalar01()); return energyRatio; }
static inline TRndGen<T>* GetRndGen() { typedef TRndGen<T> TRnd; STATIC_THREAD(TRnd) rndGenImpl; POD_STATIC_THREAD(TRnd*) rndGen((TRnd*)0); TRnd*& rnd = rndGen; if (!rnd) { rnd = &(TRnd&)rndGenImpl; } return rnd; }
void Foam::CV2D::insertGrid() { Info<< "insertInitialGrid: "; startOfInternalPoints_ = number_of_vertices(); label nVert = startOfInternalPoints_; scalar x0 = qSurf_.globalBounds().min().x(); scalar xR = qSurf_.globalBounds().max().x() - x0; int ni = int(xR/meshControls().minCellSize()) + 1; scalar deltax = xR/ni; scalar y0 = qSurf_.globalBounds().min().y(); scalar yR = qSurf_.globalBounds().max().y() - y0; int nj = int(yR/meshControls().minCellSize()) + 1; scalar deltay = yR/nj; Random rndGen(1321); scalar pert = meshControls().randomPerturbation()*min(deltax, deltay); for (int i=0; i<ni; i++) { for (int j=0; j<nj; j++) { point p(x0 + i*deltax, y0 + j*deltay, 0); if (meshControls().randomiseInitialGrid()) { p.x() += pert*(rndGen.scalar01() - 0.5); p.y() += pert*(rndGen.scalar01() - 0.5); } if (qSurf_.wellInside(p, 0.5*meshControls().minCellSize2())) { insert(Point(p.x(), p.y()))->index() = nVert++; } } } Info<< nVert << " vertices inserted" << endl; if (meshControls().objOutput()) { // Checking validity of triangulation assert(is_valid()); writeTriangles("initial_triangles.obj", true); writeFaces("initial_faces.obj", true); } }
// Prepare and initialize uniform buffer containing shader uniforms void prepareUniformBuffers() { // Allocate data for the dynamic uniform buffer object // We allocate this manually as the alignment of the offset differs between GPUs // Calculate required alignment depending on device limits size_t uboAlignment = vulkanDevice->properties.limits.minUniformBufferOffsetAlignment; dynamicAlignment = (sizeof(glm::mat4) / uboAlignment) * uboAlignment + ((sizeof(glm::mat4) % uboAlignment) > 0 ? uboAlignment : 0); size_t bufferSize = OBJECT_INSTANCES * dynamicAlignment; uboDataDynamic.model = (glm::mat4*)alignedAlloc(bufferSize, dynamicAlignment); assert(uboDataDynamic.model); std::cout << "minUniformBufferOffsetAlignment = " << uboAlignment << std::endl; std::cout << "dynamicAlignment = " << dynamicAlignment << std::endl; // Vertex shader uniform buffer block // Static shared uniform buffer object with projection and view matrix VK_CHECK_RESULT(vulkanDevice->createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffers.view, sizeof(uboVS))); // Uniform buffer object with per-object matrices VK_CHECK_RESULT(vulkanDevice->createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &uniformBuffers.dynamic, bufferSize)); // Map persistent VK_CHECK_RESULT(uniformBuffers.view.map()); VK_CHECK_RESULT(uniformBuffers.dynamic.map()); // Prepare per-object matrices with offsets and random rotations std::mt19937 rndGen(static_cast<uint32_t>(time(0))); std::normal_distribution<float> rndDist(-1.0f, 1.0f); for (uint32_t i = 0; i < OBJECT_INSTANCES; i++) { rotations[i] = glm::vec3(rndDist(rndGen), rndDist(rndGen), rndDist(rndGen)) * 2.0f * (float)M_PI; rotationSpeeds[i] = glm::vec3(rndDist(rndGen), rndDist(rndGen), rndDist(rndGen)); } updateUniformBuffers(); updateDynamicUniformBuffer(true); }
void test( size_t nThreadCount ) { ALLOC alloc; CPPUNIT_MSG( "Thread count=" << nThreadCount ); CPPUNIT_MSG("Initialize data..." ); randomGen<unsigned int> rndGen; s_nPassPerThread = s_nPassCount / nThreadCount; size_t nThread; m_aThreadData = new thread_data[ nThreadCount ]; for ( nThread = 0; nThread < nThreadCount; ++nThread ) { thread_data thData = m_aThreadData[nThread] = new char *[ s_nBlocksPerThread ]; for ( size_t i = 0; i < s_nBlocksPerThread; ++i ) { thData[i] = reinterpret_cast<char *>(alloc.allocate( rndGen( s_nMinBlockSize, s_nMaxBlockSize ), nullptr )); CPPUNIT_ASSERT( (reinterpret_cast<uintptr_t>(thData[i]) & (ALLOC::alignment - 1)) == 0 ); } } CPPUNIT_MSG("Initializatin done" ); CppUnitMini::ThreadPool pool( *this ); pool.add( new Thread<ALLOC>( pool, alloc ), nThreadCount ); nThread = 0; for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) static_cast<Thread<ALLOC> *>(*it)->m_arr = m_aThreadData[nThread++]; cds::OS::Timer timer; pool.run(); CPPUNIT_MSG( " Duration=" << pool.avgDuration() ); for ( nThread = 0; nThread < nThreadCount; ++nThread ) { thread_data thData = m_aThreadData[nThread]; for ( size_t i = 0; i < s_nBlocksPerThread; ++i ) { alloc.deallocate( reinterpret_cast<typename ALLOC::value_type *>(thData[i]), 1 ); } delete [] thData; } delete [] m_aThreadData; }
void Foam::VariableHardSphere<CloudType>::collide ( label typeIdP, label typeIdQ, vector& UP, vector& UQ, scalar& EiP, scalar& EiQ ) { CloudType& cloud(this->owner()); Random& rndGen(cloud.rndGen()); scalar mP = cloud.constProps(typeIdP).mass(); scalar mQ = cloud.constProps(typeIdQ).mass(); vector Ucm = (mP*UP + mQ*UQ)/(mP + mQ); scalar cR = mag(UP - UQ); scalar cosTheta = 2.0*rndGen.scalar01() - 1.0; scalar sinTheta = sqrt(1.0 - cosTheta*cosTheta); scalar phi = 2.0*mathematicalConstant::pi*rndGen.scalar01(); vector postCollisionRelU = cR *vector ( cosTheta, sinTheta*cos(phi), sinTheta*sin(phi) ); UP = Ucm + postCollisionRelU*mQ/(mP + mQ); UQ = Ucm - postCollisionRelU*mP/(mP + mQ); }
int main(int argc, char *argv[]) { # include "setRootCase.H" # include "createTime.H" # include "createFields.H" OFstream objFileNew("s.m"); Random rndGen(label(0)); autoPtr<pdf> p ( pdf::New(pdfDictionary, rndGen) ); scalar xMin = p->minValue(); scalar xMax = p->maxValue(); for(label i=0;i<nSamples;i++) { scalar ps = p->sample(); label n = label((ps-xMin)*nIntervals/(xMax-xMin)); //Info << "p[" << i << "] = " << ps << ", n = " << n << endl; samples[n]++; } for(label i=0;i<nIntervals;i++) { scalar x = xMin + i*(xMax-xMin)/(nIntervals-1); objFileNew << x << " \t" << samples[i] << endl; } Info << "End\n" << endl; return 0; }
void Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::collide ( label typeIdP, label typeIdQ, vector& UP, vector& UQ, scalar& EiP, scalar& EiQ ) { CloudType& cloud(this->owner()); Random& rndGen(cloud.rndGen()); scalar inverseCollisionNumber = 1/relaxationCollisionNumber_; // Larsen Borgnakke internal energy redistribution part. Using the serial // application of the LB method, as per the INELRS subroutine in Bird's // DSMC0R.FOR scalar preCollisionEiP = EiP; scalar preCollisionEiQ = EiQ; scalar iDofP = cloud.constProps(typeIdP).internalDegreesOfFreedom(); scalar iDofQ = cloud.constProps(typeIdQ).internalDegreesOfFreedom(); scalar omegaPQ = 0.5 *( cloud.constProps(typeIdP).omega() + cloud.constProps(typeIdQ).omega() ); scalar mP = cloud.constProps(typeIdP).mass(); scalar mQ = cloud.constProps(typeIdQ).mass(); scalar mR = mP*mQ/(mP + mQ); vector Ucm = (mP*UP + mQ*UQ)/(mP + mQ); scalar cRsqr = magSqr(UP - UQ); scalar availableEnergy = 0.5*mR*cRsqr; scalar ChiB = 2.5 - omegaPQ; if (iDofP > 0) { if (inverseCollisionNumber > rndGen.scalar01()) { availableEnergy += preCollisionEiP; scalar ChiA = 0.5*iDofP; EiP = energyRatio(ChiA, ChiB)*availableEnergy; availableEnergy -= EiP; } } if (iDofQ > 0) { if (inverseCollisionNumber > rndGen.scalar01()) { availableEnergy += preCollisionEiQ; // Change to general LB ratio calculation scalar energyRatio = 1.0 - pow(rndGen.scalar01(),(1.0/ChiB)); EiQ = energyRatio*availableEnergy; availableEnergy -= EiQ; } } // Rescale the translational energy scalar cR = sqrt(2.0*availableEnergy/mR); // Variable Hard Sphere collision part scalar cosTheta = 2.0*rndGen.scalar01() - 1.0; scalar sinTheta = sqrt(1.0 - cosTheta*cosTheta); scalar phi = 2.0*mathematicalConstant::pi*rndGen.scalar01(); vector postCollisionRelU = cR *vector ( cosTheta, sinTheta*cos(phi), sinTheta*sin(phi) ); UP = Ucm + postCollisionRelU*mQ/(mP + mQ); UQ = Ucm - postCollisionRelU*mP/(mP + mQ); }
void radiationWallPatch::controlParticle(dsmcParcel& p, dsmcParcel::trackingData& td) { measurePropertiesBeforeControl(p); vector& U = p.U(); scalar& ERot = p.ERot(); label& vibLevel = p.vibLevel(); label typeId = p.typeId(); // new stuff scalar Etrans = 0.5*magSqr(U)*cloud_.constProps(typeId).mass(); scalar EcTot = Etrans + ERot + vibLevel*physicoChemical::k.value()*cloud_.constProps(typeId).thetaV(); EcTot_ += EcTot; // vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude scalar U_dot_nw = U & nw; // Wall tangential velocity (flow direction) vector Ut = U - U_dot_nw*nw; Random& rndGen(cloud_.rndGen()); while (mag(Ut) < SMALL) { // If the incident velocity is parallel to the face normal, no // tangential direction can be chosen. Add a perturbation to the // incoming velocity and recalculate. U = vector ( U.x()*(0.8 + 0.2*rndGen.scalar01()), U.y()*(0.8 + 0.2*rndGen.scalar01()), U.z()*(0.8 + 0.2*rndGen.scalar01()) ); U_dot_nw = U & nw; Ut = U - U_dot_nw*nw; } // Wall tangential unit vector vector tw1 = Ut/mag(Ut); // Other tangential unit vector vector tw2 = nw^tw1; const scalar& T = TwallRad_; scalar mass = cloud_.constProps(typeId).mass(); scalar rotationalDof = cloud_.constProps(typeId).rotationalDegreesOfFreedom(); scalar vibrationalDof = cloud_.constProps(typeId).vibrationalDegreesOfFreedom(); U = sqrt(physicoChemical::k.value()*T/mass) *( rndGen.GaussNormal()*tw1 + rndGen.GaussNormal()*tw2 - sqrt(-2.0*log(max(1 - rndGen.scalar01(), VSMALL)))*nw ); U += velocity_; ERot = cloud_.equipartitionRotationalEnergy(T, rotationalDof); vibLevel = cloud_.equipartitionVibrationalEnergyLevel(T, vibrationalDof, typeId); measurePropertiesAfterControl(p, 0.0); }
void dsmcMixedDiffuseSpecularSphericalPatch::controlParticle(dsmcParcel& p, dsmcParcel::trackingData& td) { measurePropertiesBeforeControl(p); vector& U = p.U(); scalar& ERot = p.ERot(); label& vibLevel = p.vibLevel(); label typeId = p.typeId(); // label wppIndex = p.patch(p.face()); // const polyPatch& patch = mesh_.boundaryMesh()[wppIndex]; // label wppLocalFace = patch.whichFace(p.face()); vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude scalar U_dot_nw = U & nw; Random& rndGen(cloud_.rndGen()); if (diffuseFraction_ > rndGen.scalar01()) { // Diffuse reflection // Wall tangential velocity (flow direction) vector Ut = U - U_dot_nw*nw; while (mag(Ut) < SMALL) { // If the incident velocity is parallel to the face normal, no // tangential direction can be chosen. Add a perturbation to the // incoming velocity and recalculate. U = vector ( U.x()*(0.8 + 0.2*rndGen.scalar01()), U.y()*(0.8 + 0.2*rndGen.scalar01()), U.z()*(0.8 + 0.2*rndGen.scalar01()) ); U_dot_nw = U & nw; Ut = U - U_dot_nw*nw; } // Wall tangential unit vector vector tw1 = Ut/mag(Ut); // Other tangential unit vector vector tw2 = nw^tw1; // scalar T = boundaryT_.boundaryField()[wppIndex][wppLocalFace]; scalar T = wallTemperature_; scalar mass = cloud_.constProps(typeId).mass(); scalar rotationalDof = cloud_.constProps(typeId).rotationalDegreesOfFreedom(); scalar vibrationalDof = cloud_.constProps(typeId).vibrationalDegreesOfFreedom(); U = sqrt(physicoChemical::k.value()*T/mass) *( rndGen.GaussNormal()*tw1 + rndGen.GaussNormal()*tw2 - sqrt(-2.0*log(max(1 - rndGen.scalar01(), VSMALL)))*nw ); scalar theta = 0.0; //longitude scalar phi = 0.0; //latitude scalar radius = 0.0; radius = mag(centrePoint_ - p.position()); phi = acos(p.position().y()/radius); theta = atan(p.position().x()/p.position().z()); if(p.position().z() < 0 && p.position().x() > 0) { theta *= -1.0; scalar diff = pi/2.0 - theta; theta = diff + pi/2.0; } if(p.position().z() < 0 && p.position().x() < 0) { theta += pi; } // if(p.position().y() < 500) // { // Info << "radius = " << radius << endl; // Info << "p.position() = " << p.position() << endl; // Info << "phi = " << phi*57.2957795 << endl; // Info << "theta = " << theta*57.2957795 << endl; // } // add wall velocity vector uNew = vector::zero; scalar linearVelocityXPlane = 0.0; scalar linearVelocityYPlane = 0.0; scalar linearVelocityZPlane = 0.0; linearVelocityXPlane = angularVelocityXPlane_*radius; linearVelocityYPlane = angularVelocityYPlane_*radius; linearVelocityZPlane = angularVelocityZPlane_*radius; // if(p.position().y() < 500) // { uNew.x() = linearVelocityYPlane*cos(theta)*fabs(sin(phi)); uNew.z() = -linearVelocityYPlane*sin(theta)*fabs(sin(phi)); // } // if( pi < theta <= twoPi) // { // uNew.x() = -linearVelocityYPlane*cos(theta); // uNew.z() = linearVelocityYPlane*sin(theta); // } // Info << "Ubefore = " << U << endl; // if(p.position().y() < 500) // { // Info << "uNew = " << uNew << endl; // } U += uNew; // Info << "Uafter = " << U << endl; ERot = cloud_.equipartitionRotationalEnergy(T, rotationalDof); vibLevel = cloud_.equipartitionVibrationalEnergyLevel(T, vibrationalDof, typeId); } else { // Specular reflection if (U_dot_nw > 0.0) { U -= 2.0*U_dot_nw*nw; } } measurePropertiesAfterControl(p, 0.0); }
void FeaturePointsRANSAC::runRANSAC(Mat img, vector<pair<string, vector<shared_ptr<imageprocessing::Patch>>>> landmarkData, MorphableModel mm, float thresholdForDatapointFitsModel, int numIter/*=0*/, int numClosePointsRequiredForGoodFit/*=4*/, int minPointsToFitModel/*=3*/) { if(numIter==0) { // Calculate/estimate how many iterations we should run (see Wikipedia) numIter = 2500; } numIter = 50; minPointsToFitModel = 3; bool useSVD = false; thresholdForDatapointFitsModel = 30.0f; // Note: Doesn't seem to make sense to use more than 3 points for the initial projection. With 4 (and SVD instead of inv()), the projection of the other model-LMs is quite wrong already. // So: minPointsToFitModel == 3 unchangeable! (hm, really...?) // RANSAC general TODO: Bei Nase beruecksichtigen, dass das Gesicht nicht auf dem Kopf stehen darf? (da sonst das feature nicht gefunden wuerde, nicht symmetrisch top/bottom) // TODO Use 1/2 of detected face patch = IED, then discard all model proposals that are smaller than 2/3 IED or so? Make use of face-box... // Take face-box as probability of a face there... then also PSM output... then take regions where the FD doesn't have a response, e.g. Skin, Circles etc... and also try PSM there. // Build an "iterative global face-probability map" with all those detectors? // use additional feature spaces (gabor etc) // // Another Idea: Use 3 detected points, project the 3DMM, then, around a possible 4th point, use a detector and search this region! // (I guess I need a dynamic detector map for this :-) Attaching to Image not a good idea... (really?)... use a Master-detector or so? Hm I kind of already have that (Casc.Fac.Feat...)) // only temporary to print the 3DMM vector<string> modelPointsToRender; modelPointsToRender.push_back("nose_tip"); modelPointsToRender.push_back("mouth_rc"); modelPointsToRender.push_back("mouth_lc"); modelPointsToRender.push_back("chin"); modelPointsToRender.push_back("reye_c"); modelPointsToRender.push_back("leye_c"); modelPointsToRender.push_back("rear_c"); modelPointsToRender.push_back("lear_c"); modelPointsToRender.push_back("mouth_ulb"); modelPointsToRender.push_back("mouth_llb"); modelPointsToRender.push_back("rebr_olc"); modelPointsToRender.push_back("lebr_olc"); modelPointsToRender.push_back("rear_ic"); modelPointsToRender.push_back("lear_ic"); modelPointsToRender.push_back("rear_lobe"); modelPointsToRender.push_back("lear_lobe"); modelPointsToRender.push_back("rear_oc"); modelPointsToRender.push_back("lear_oc"); modelPointsToRender.push_back("rear_uc"); modelPointsToRender.push_back("lear_uc"); unsigned int iterations = 0; //boost::random::mt19937 rndGen(time(0)); // Pseudo-random number generators should not be constructed (initialized) frequently during program execution, for two reasons... see boost doc. But this is not a problem as long as we don't call runRANSAC too often (e.g. every frame). boost::random::mt19937 rndGen(1); // TODO: Use C++11 // Todo: Probably faster if I convert all LMs to Point2i beforehands, so I only do it once. // Maybe I want the patch certainty later, then I need to make a pair<Point2i, float> or so. But the rest of the Patch I won't need for certain. vector<int> indexMap; // This is created so each point of all landmarks together has the same probability of being chosen (eg we have more eyes -> eyes get chosen more often) for (unsigned int i=0; i<landmarkData.size(); ++i) { for (unsigned int j=0; j<landmarkData[i].second.size(); ++j) { indexMap.push_back(i); } } boost::random::uniform_int_distribution<> rndLandmarkDistr(0, indexMap.size()-1); // threshold around 1/3 IED? // some LMs wrong? nose_tip? No vector<vector<pair<string, Point2f>>> bestConsensusSets; while (iterations < numIter) { ++iterations; // maybe_inliers := #minPointsToFitModel randomly selected values from data vector<pair<string, shared_ptr<imageprocessing::Patch> > > maybeInliersPatches; // CHANGED TO PATCH unsigned int distinctFfpsChosen = 0; // we don't need this, we could use size of alreadyChosenFfps? set<int> alreadyChosenFfps; while(distinctFfpsChosen < minPointsToFitModel) { int whichFfp = indexMap[rndLandmarkDistr(rndGen)]; // Find out which ffp to take boost::random::uniform_int_distribution<> rndCandidateDistr(0, landmarkData[whichFfp].second.size()-1); // this could be taken out of the loop and only done once for each landmark-type int whichPoint = rndCandidateDistr(rndGen); // Find out which detected point from the selected ffp to take string thePointLMName = landmarkData[whichFfp].first; // The LM we took (e.g. reye_c) shared_ptr<imageprocessing::Patch> thePointPatch = landmarkData[whichFfp].second[whichPoint]; // The patch (with 2D-coords) we took // CHANGED TO PATCH // Check if we didn't already choose this FFP-type if(alreadyChosenFfps.find(whichFfp)==alreadyChosenFfps.end()) { // We didn't already choose this FFP-type: maybeInliersPatches.push_back(make_pair(thePointLMName, thePointPatch)); alreadyChosenFfps.insert(whichFfp); ++distinctFfpsChosen; } } // We got #minPointsToFitModel distinct maybe_inliers, go on // == maybeInliers // maybe_model := model parameters fitted to maybeInliers vector<pair<string, Point2f> > maybeInliers; /*maybeInliersDbg.push_back(make_pair("reye_c", Point2f(100.0f, 100.0f))); maybeInliersDbg.push_back(make_pair("leye_c", Point2f(160.0f, 100.0f))); //maybeInliersDbg.push_back(make_pair("mouth_rc", Point2f(110.0f, 180.0f))); maybeInliersDbg.push_back(make_pair("mouth_lc", Point2f(150.0f, 180.0f)));*/ for (unsigned int i=0; i<maybeInliersPatches.size(); ++i) { maybeInliers.push_back(make_pair(maybeInliersPatches[i].first, Point2f((float)maybeInliersPatches[i].second->getX(), (float)maybeInliersPatches[i].second->getY()))); } LandmarksVerticesPair lmVertPairAtOrigin = getCorrespondingLandmarkpointsAtOriginFrom3DMM(maybeInliers, mm); // Calculate s and t // Todo: Using this method, we don't check if the face is facing us or not. Somehow check this. // E.g. give the LMs color, or text, or some math? pair<Mat, Mat> projection = calculateProjection(lmVertPairAtOrigin.landmarks, lmVertPairAtOrigin.vertices); Mat s = projection.first; Mat t = projection.second; Mat outimg = img.clone(); // CHANGED 2013 //drawFull3DMMProjection(outimg, lmVertPairAtOrigin.verticesMean, lmVertPairAtOrigin.landmarksMean, s, t); //vector<pair<string, Point2f> > pointsInImage = projectVerticesToImage(modelPointsToRender, lmVertPairAtOrigin.verticesMean, lmVertPairAtOrigin.landmarksMean, s, t); //drawAndPrintLandmarksInImage(outimg, pointsInImage); // TODO COMMENTED 2013 //Logger->drawFfpsSmallSquare(outimg, maybeInliers); // TODO: Should not call this directly! Make a LogImg... function! //drawLandmarksText(outimg, maybeInliers); //imwrite("out\\a_ransac_initialPoints.png", outimg); // END // consensus_set := maybe_inliers vector<pair<string, Point2f> > consensusSet = maybeInliers; // (TODO? get the IED of the current projection, to calculate the threshold. Hmm - what if I dont have the eye-LMs... Somehow make thresh dynamic (because of different face-sizes! absolute Pixels not good!)) // But the FaceDetector knows the face-box size!!! // for every point in data not in maybe_inliers for (unsigned int i=0; i<indexMap.size(); ++i) { // This could be made faster, by using i<landmarkData.size(), and then skip the whole landmark int whichFfp = indexMap[i]; // Find out which ffp to take // Check if we didn't already choose this FFP-type if(alreadyChosenFfps.find(whichFfp)==alreadyChosenFfps.end()) { // We didn't already choose this FFP-type: alreadyChosenFfps.insert(whichFfp); ++distinctFfpsChosen; // Loop through all candidates of this FFP-type. If several fit, use the one with the lowest error. vector<double> currentFfpDistances; //TODO pre-Alloc with ... for (unsigned int j=0; j<landmarkData[whichFfp].second.size(); ++j) { // if point fits maybe_model with an error smaller than t // Fit the point with current model: string thePointLMName = landmarkData[whichFfp].first; // The LM we took (e.g. reye_c) shared_ptr<imageprocessing::Patch> thePointPatch = landmarkData[whichFfp].second[j]; // The patch (with 2D-coords) we took // // CHANGED TO PATCH // get "thePointLMName" vertex from 3DMM, project into 2D with s, t vector<string> theNewLmToProject; theNewLmToProject.push_back(thePointLMName); vector<pair<string, Point2f> > theNewLmInImage = projectVerticesToImage(theNewLmToProject, lmVertPairAtOrigin.verticesMean, lmVertPairAtOrigin.landmarksMean, s, t, mm); // error of theNewLmInImage[0] - thePointPatch < t ? cv::Vec2f theNewLm(theNewLmInImage[0].second.x, theNewLmInImage[0].second.y); cv::Vec2f theNewPointPatch((float)thePointPatch->getX(), (float)thePointPatch->getY()); double distance = cv::norm(theNewLm, theNewPointPatch, cv::NORM_L2); currentFfpDistances.push_back(distance); } vector<double>::iterator beforeItr = min_element(currentFfpDistances.begin(), currentFfpDistances.end()); if(*beforeItr > thresholdForDatapointFitsModel) { // None of the candidates for the current Ffp fit the model well. Don't add anything to the consensusSet. } else { // We found a candidate that fits the model, add it to the consensusSet! (and continue with the next Ffp) int positionOfMinimumElement = distance(currentFfpDistances.begin(), beforeItr); shared_ptr<imageprocessing::Patch> thePointPatch = landmarkData[whichFfp].second[positionOfMinimumElement]; // CHANGED TO PATCH Point2f theNewPointPatch((float)thePointPatch->getX(), (float)thePointPatch->getY()); consensusSet.push_back(make_pair(landmarkData[whichFfp].first, theNewPointPatch)); } } } // We went through all Ffp's. // if the number of elements in consensus_set is > d (this implies that we may have found a good model, now test how good it is) if (consensusSet.size()<numClosePointsRequiredForGoodFit) { continue; // We didn't find a good model, the consensusSet only consists of the points projected (e.g. 3). } // this_model := model parameters fitted to all points in consensus_set LandmarksVerticesPair consensusSetLmVertPairAtOrigin = getCorrespondingLandmarkpointsAtOriginFrom3DMM(consensusSet, mm); // Todo: It's kind of not clear if this expects centered 2D LMs or not-centered (it's not-centered) // Todo: Using this method, we don't check if the face is facing us or not. Somehow check this. pair<Mat, Mat> projectionC = calculateProjection(consensusSetLmVertPairAtOrigin.landmarks, consensusSetLmVertPairAtOrigin.vertices); Mat sc = projectionC.first; Mat tc = projectionC.second; Mat outimgConsensus = img.clone(); // TODO 2013 changed drawFull3DMMProjection(outimgConsensus, consensusSetLmVertPairAtOrigin.verticesMean, consensusSetLmVertPairAtOrigin.landmarksMean, sc, tc, mm); vector<pair<string, Point2f> > pointsInImageC = projectVerticesToImage(modelPointsToRender, consensusSetLmVertPairAtOrigin.verticesMean, consensusSetLmVertPairAtOrigin.landmarksMean, sc, tc, mm); drawAndPrintLandmarksInImage(outimgConsensus, pointsInImageC); // TODO 2013 CHANGED drawFfpsSmallSquare(outimgConsensus, consensusSet); // TODO: Should not call this directly! Make a LogImg... function! drawLandmarksText(outimgConsensus, consensusSet); imwrite("out\\a_ransac_ConsensusSet.png", outimgConsensus); // END // this_error := a measure of how well this_model fits these points // TODO // we could check how many of the 3dmm LMs projected into the model with s and t are inside the actual image. If they are far off, the model is not good. (?) // also check this for the three initial points? // or better use some kind of matrix/projection/regularisation, that those transformations doesn't exist in the first place... // Check for number of points AND some kind of error measure? if(bestConsensusSets.empty()) { bestConsensusSets.push_back(consensusSet); } else { if(consensusSet.size()==bestConsensusSets[0].size()) { bestConsensusSets.push_back(consensusSet); } else if (consensusSet.size()>bestConsensusSets[0].size()) { bestConsensusSets.clear(); bestConsensusSets.push_back(consensusSet); } } Loggers->getLogger("shapemodels").debug("Finished one iteration."); } // Hmm, the bestConsensusSets is not unique? Doubled sets? (print them?) Write a comparator for two landmarks (make a landmark class?), then for two LM-sets, etc. for (unsigned int i=0; i<bestConsensusSets.size(); ++i) { // TODO 2013 CHANGED //Mat output = img->data_matbgr.clone(); //drawAndPrintLandmarksInImage(output, bestConsensusSets[i]); //Logger->drawFfpsSmallSquare(output, bestConsensusSets[i]); // TODO: Should not call this directly! Make a LogImg... function! Make these Logger-functions private? //drawLandmarksText(output, bestConsensusSets[i]); //stringstream sstm; //sstm << "out\\a_ransac_ConsensusSet_" << i << ".png"; //string fn = sstm.str(); //imwrite(fn, output); // END } for (unsigned int i=0; i<bestConsensusSets.size(); ++i) { for (unsigned int j=0; j<bestConsensusSets[i].size(); ++j) { cout << "[" << bestConsensusSets[i][j].first << " " << bestConsensusSets[i][j].second << "], "; } cout << endl; } }
forAll(regionsAddressing, regionI) { scalar oldTol = treeType::perturbTol(); treeType::perturbTol() = tolerance(); indirectRegionPatches_.set ( regionI, new indirectTriSurface ( IndirectList<labelledTri> ( surface(), regionsAddressing[regionI] ), surface().points() ) ); // Calculate bb without constructing local point numbering. treeBoundBox bb(Zero, Zero); if (indirectRegionPatches_[regionI].size()) { label nPoints; PatchTools::calcBounds ( indirectRegionPatches_[regionI], bb, nPoints ); // if (nPoints != surface().points().size()) // { // WarningInFunction // << "Surface does not have compact point numbering. " // << "Of " << surface().points().size() // << " only " << nPoints // << " are used." // << " This might give problems in some routines." // << endl; // } // Random number generator. Bit dodgy since not exactly // random ;-) Random rndGen(65431); // Slightly extended bb. Slightly off-centred just so // on symmetric geometry there are fewer face/edge // aligned items. bb = bb.extend(rndGen, 1e-4); bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); } treeByRegion_.set ( regionI, new treeType ( treeDataIndirectTriSurface ( true, indirectRegionPatches_[regionI], tolerance() ), bb, maxTreeDepth(), // maxLevel 10, // leafsize 3.0 // duplicity ) ); treeType::perturbTol() = oldTol; }
void dsmcMixedDiffuseSpecularWallRotationPatch::controlParticle(dsmcParcel& p, dsmcParcel::trackingData& td) { measurePropertiesBeforeControl(p); vector& U = p.U(); scalar& ERot = p.ERot(); label& vibLevel = p.vibLevel(); label typeId = p.typeId(); // label wppIndex = p.patch(p.face()); // const polyPatch& patch = mesh_.boundaryMesh()[wppIndex]; // label wppLocalFace = patch.whichFace(p.face()); vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude scalar U_dot_nw = U & nw; Random& rndGen(cloud_.rndGen()); if (diffuseFraction_ > rndGen.scalar01()) { // Diffuse reflection // Wall tangential velocity (flow direction) vector Ut = U - U_dot_nw*nw; while (mag(Ut) < SMALL) { // If the incident velocity is parallel to the face normal, no // tangential direction can be chosen. Add a perturbation to the // incoming velocity and recalculate. U = vector ( U.x()*(0.8 + 0.2*rndGen.scalar01()), U.y()*(0.8 + 0.2*rndGen.scalar01()), U.z()*(0.8 + 0.2*rndGen.scalar01()) ); U_dot_nw = U & nw; Ut = U - U_dot_nw*nw; } // Wall tangential unit vector vector tw1 = Ut/mag(Ut); // Other tangential unit vector vector tw2 = nw^tw1; // scalar T = boundaryT_.boundaryField()[wppIndex][wppLocalFace]; scalar T = wallTemperature_; scalar mass = cloud_.constProps(typeId).mass(); scalar rotationalDof = cloud_.constProps(typeId).rotationalDegreesOfFreedom(); scalar vibrationalDof = cloud_.constProps(typeId).vibrationalDegreesOfFreedom(); U = sqrt(physicoChemical::k.value()*T/mass) *( rndGen.GaussNormal()*tw1 + rndGen.GaussNormal()*tw2 - sqrt(-2.0*log(max(1 - rndGen.scalar01(), VSMALL)))*nw ); // add wall velocity vector uNew = ( (p.position() - centrePoint_)/mag((p.position() - centrePoint_)) ) ^ rotationAxis_; uNew /= mag(uNew); uNew *= wallVelocity_; U += uNew; ERot = cloud_.equipartitionRotationalEnergy(T, rotationalDof); vibLevel = cloud_.equipartitionVibrationalEnergyLevel(T, vibrationalDof, typeId); } else { // Specular reflection if (U_dot_nw > 0.0) { U -= 2.0*U_dot_nw*nw; } } measurePropertiesAfterControl(p, 0.0); }
void dsmcDiffuseCatalyticWallPatch::controlParticle(dsmcParcel& p, dsmcParcel::trackingData& td) { measurePropertiesBeforeControl(p); vector& U = p.U(); scalar& ERot = p.ERot(); label& vibLevel = p.vibLevel(); label& ELevel = p.ELevel(); label typeId = p.typeId(); label iD = findIndex(catalysisTypeIds_, typeId); if(iD == -1) { vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude scalar U_dot_nw = U & nw; // Wall tangential velocity (flow direction) vector Ut = U - U_dot_nw*nw; Random& rndGen(cloud_.rndGen()); while (mag(Ut) < SMALL) { // If the incident velocity is parallel to the face normal, no // tangential direction can be chosen. Add a perturbation to the // incoming velocity and recalculate. U = vector ( U.x()*(0.8 + 0.2*rndGen.scalar01()), U.y()*(0.8 + 0.2*rndGen.scalar01()), U.z()*(0.8 + 0.2*rndGen.scalar01()) ); U_dot_nw = U & nw; Ut = U - U_dot_nw*nw; } // Wall tangential unit vector vector tw1 = Ut/mag(Ut); // Other tangential unit vector vector tw2 = nw^tw1; const scalar& T = temperature_; scalar mass = cloud_.constProps(typeId).mass(); scalar rotationalDof = cloud_.constProps(typeId).rotationalDegreesOfFreedom(); scalar vibrationalDof = cloud_.constProps(typeId).vibrationalDegreesOfFreedom(); List<label> degeneracyList = cloud_.constProps(typeId).degeneracyList(); List<scalar> electronicEnergyList = cloud_.constProps(typeId).electronicEnergyList(); U = sqrt(physicoChemical::k.value()*T/mass) *( rndGen.GaussNormal()*tw1 + rndGen.GaussNormal()*tw2 - sqrt(-2.0*log(max(1 - rndGen.scalar01(), VSMALL)))*nw ); U += velocity_; ERot = cloud_.equipartitionRotationalEnergy(T, rotationalDof); vibLevel = cloud_.equipartitionVibrationalEnergyLevel(T, vibrationalDof, typeId); ELevel = cloud_.equipartitionElectronicLevel(T, degeneracyList, electronicEnergyList, typeId); measurePropertiesAfterControl(p, 0.0); } else { // label newTypeId = catalysedTypeIds_[iD]; vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude scalar U_dot_nw = U & nw; // Wall tangential velocity (flow direction) vector Ut = U - U_dot_nw*nw; Random& rndGen(cloud_.rndGen()); while (mag(Ut) < SMALL) { // If the incident velocity is parallel to the face normal, no // tangential direction can be chosen. Add a perturbation to the // incoming velocity and recalculate. U = vector ( U.x()*(0.8 + 0.2*rndGen.scalar01()), U.y()*(0.8 + 0.2*rndGen.scalar01()), U.z()*(0.8 + 0.2*rndGen.scalar01()) ); U_dot_nw = U & nw; Ut = U - U_dot_nw*nw; } // Wall tangential unit vector vector tw1 = Ut/mag(Ut); // Other tangential unit vector vector tw2 = nw^tw1; const scalar& T = temperature_; p.typeId() = catalysedTypeIds_[iD]; label newTypeId = catalysedTypeIds_[iD]; scalar mass = cloud_.constProps(newTypeId).mass(); label rotationalDof = cloud_.constProps(newTypeId).rotationalDegreesOfFreedom(); label vibrationalDof = cloud_.constProps(newTypeId).vibrationalDegreesOfFreedom(); List<label> degeneracyList = cloud_.constProps(newTypeId).degeneracyList(); List<scalar> electronicEnergyList = cloud_.constProps(newTypeId).electronicEnergyList(); U = sqrt(physicoChemical::k.value()*T/mass) *( rndGen.GaussNormal()*tw1 + rndGen.GaussNormal()*tw2 - sqrt(-2.0*log(max(1 - rndGen.scalar01(), VSMALL)))*nw ); U += velocity_; ERot = cloud_.equipartitionRotationalEnergy(T, rotationalDof); vibLevel = cloud_.equipartitionVibrationalEnergyLevel(T, vibrationalDof, newTypeId); ELevel = cloud_.equipartitionElectronicLevel(T, degeneracyList, electronicEnergyList, newTypeId); measurePropertiesAfterControl(p, heatOfReaction_[iD]); // Info << "cloud_.constProps(p.typeId()).charge() = " << cloud_.constProps(p.typeId()).charge() << endl; } // else // { // if(typeId == catalysisTypeIds_[0] && (cloud_.rndGen().scalar01() > 0.5)) // { // td.keepParticle = false; //delete every 2nd nitrogen atom (need 2 for recombination) // } // else // { // p.typeId() = catalysedTypeIds_[0]; // change from N to N2 // typeId = p.typeId(); // nitrogenSwitch_ = !nitrogenSwitch_; // } // // if(typeId == catalysisTypeIds_[1] && (cloud_.rndGen().scalar01() > 0.5)) // { // td.keepParticle = false; //delete every 2nd oxygen atom (need 2 for recombination) // } // else // { // p.typeId() = catalysedTypeIds_[1]; // change from O to O2 // typeId = p.typeId(); // oxygenSwitch_ = !oxygenSwitch_; // } // // if(nitrogenSwitch_ == true || oxygenSwitch_ == true) // { // vector nw = p.normal(); // nw /= mag(nw); // // // Normal velocity magnitude // scalar U_dot_nw = U & nw; // // // Wall tangential velocity (flow direction) // vector Ut = U - U_dot_nw*nw; // // Random& rndGen(cloud_.rndGen()); // // while (mag(Ut) < SMALL) // { // // If the incident velocity is parallel to the face normal, no // // tangential direction can be chosen. Add a perturbation to the // // incoming velocity and recalculate. // // U = vector // ( // U.x()*(0.8 + 0.2*rndGen.scalar01()), // U.y()*(0.8 + 0.2*rndGen.scalar01()), // U.z()*(0.8 + 0.2*rndGen.scalar01()) // ); // // U_dot_nw = U & nw; // // Ut = U - U_dot_nw*nw; // } // // // Wall tangential unit vector // vector tw1 = Ut/mag(Ut); // // // Other tangential unit vector // vector tw2 = nw^tw1; // // const scalar& T = temperature_; // // scalar mass = cloud_.constProps(typeId).mass(); // // scalar rotationalDof = cloud_.constProps(typeId).rotationalDegreesOfFreedom(); // // scalar vibrationalDof = cloud_.constProps(typeId).vibrationalDegreesOfFreedom(); // // U = // sqrt(physicoChemical::k.value()*T/mass) // *( // rndGen.GaussNormal()*tw1 // + rndGen.GaussNormal()*tw2 // - sqrt(-2.0*log(max(1 - rndGen.scalar01(), VSMALL)))*nw // ); // // U += velocity_; // // ERot = cloud_.equipartitionRotationalEnergy(T, rotationalDof); // // vibLevel = cloud_.equipartitionVibrationalEnergyLevel(T, vibrationalDof, typeId); // } // } }
void timeVaryingMappedFixedValueFvPatchField<Type>::readSamplePoints() { // Read the sample points pointIOField samplePoints ( IOobject ( "points", this->db().time().constant(), "boundaryData"/this->patch().name(), this->db(), IOobject::MUST_READ, IOobject::AUTO_WRITE, false ) ); const fileName samplePointsFile = samplePoints.filePath(); if (debug) { Info<< "timeVaryingMappedFixedValueFvPatchField :" << " Read " << samplePoints.size() << " sample points from " << samplePointsFile << endl; } // Determine coordinate system from samplePoints if (samplePoints.size() < 3) { FatalErrorIn ( "timeVaryingMappedFixedValueFvPatchField<Type>::readSamplePoints()" ) << "Only " << samplePoints.size() << " points read from file " << samplePoints.objectPath() << nl << "Need at least three non-colinear samplePoints" << " to be able to interpolate." << "\n on patch " << this->patch().name() << " of points " << samplePoints.name() << " in file " << samplePoints.objectPath() << exit(FatalError); } const point& p0 = samplePoints[0]; // Find furthest away point vector e1; label index1 = -1; scalar maxDist = -GREAT; for (label i = 1; i < samplePoints.size(); i++) { const vector d = samplePoints[i] - p0; scalar magD = mag(d); if (magD > maxDist) { e1 = d/magD; index1 = i; maxDist = magD; } } // Find point that is furthest away from line p0-p1 const point& p1 = samplePoints[index1]; label index2 = -1; maxDist = -GREAT; for (label i = 1; i < samplePoints.size(); i++) { if (i != index1) { const point& p2 = samplePoints[i]; vector e2(p2 - p0); e2 -= (e2&e1)*e1; scalar magE2 = mag(e2); if (magE2 > maxDist) { index2 = i; maxDist = magE2; } } } if (index2 == -1) { FatalErrorIn ( "timeVaryingMappedFixedValueFvPatchField<Type>::readSamplePoints()" ) << "Cannot find points that make valid normal." << nl << "Have so far points " << p0 << " and " << p1 << "Need at least three sample points which are not in a line." << "\n on patch " << this->patch().name() << " of points " << samplePoints.name() << " in file " << samplePoints.objectPath() << exit(FatalError); } vector n = e1^(samplePoints[index2]-p0); n /= mag(n); if (debug) { Info<< "timeVaryingMappedFixedValueFvPatchField :" << " Used points " << p0 << ' ' << samplePoints[index1] << ' ' << samplePoints[index2] << " to define coordinate system with normal " << n << endl; } referenceCS_.reset ( new coordinateSystem ( "reference", p0, // origin n, // normal e1 // 0-axis ) ); tmp<vectorField> tlocalVertices ( referenceCS().localPosition(samplePoints) ); vectorField& localVertices = tlocalVertices(); const boundBox bb(localVertices, true); const point bbMid(bb.midpoint()); if (debug) { Info<< "timeVaryingMappedFixedValueFvPatchField :" << " Perturbing points with " << perturb_ << " fraction of a random position inside " << bb << " to break any ties on regular meshes." << nl << endl; } Random rndGen(123456); forAll(localVertices, i) { localVertices[i] += perturb_ *(rndGen.position(bb.min(), bb.max())-bbMid); }
void Foam::MixedDiffuseSpecular<CloudType>::correct ( typename CloudType::parcelType& p ) { vector& U = p.U(); scalar& Ei = p.Ei(); label typeId = p.typeId(); const label wppIndex = p.patch(); const polyPatch& wpp = p.mesh().boundaryMesh()[wppIndex]; label wppLocalFace = wpp.whichFace(p.face()); const vector nw = p.normal(); // Normal velocity magnitude scalar U_dot_nw = U & nw; CloudType& cloud(this->owner()); Random& rndGen(cloud.rndGen()); if (diffuseFraction_ > rndGen.scalar01()) { // Diffuse reflection // Wall tangential velocity (flow direction) vector Ut = U - U_dot_nw*nw; while (mag(Ut) < small) { // If the incident velocity is parallel to the face normal, no // tangential direction can be chosen. Add a perturbation to the // incoming velocity and recalculate. U = vector ( U.x()*(0.8 + 0.2*rndGen.scalar01()), U.y()*(0.8 + 0.2*rndGen.scalar01()), U.z()*(0.8 + 0.2*rndGen.scalar01()) ); U_dot_nw = U & nw; Ut = U - U_dot_nw*nw; } // Wall tangential unit vector vector tw1 = Ut/mag(Ut); // Other tangential unit vector vector tw2 = nw^tw1; scalar T = cloud.boundaryT().boundaryField()[wppIndex][wppLocalFace]; scalar mass = cloud.constProps(typeId).mass(); direction iDof = cloud.constProps(typeId).internalDegreesOfFreedom(); U = sqrt(physicoChemical::k.value()*T/mass) *( rndGen.scalarNormal()*tw1 + rndGen.scalarNormal()*tw2 - sqrt(-2.0*log(max(1 - rndGen.scalar01(), vSmall)))*nw ); U += cloud.boundaryU().boundaryField()[wppIndex][wppLocalFace]; Ei = cloud.equipartitionInternalEnergy(T, iDof); } else { // Specular reflection if (U_dot_nw > 0.0) { U -= 2.0*U_dot_nw*nw; } } }
void dsmcCLLWallPatch::controlParticle(dsmcParcel& p, dsmcParcel::trackingData& td) { measurePropertiesBeforeControl(p); vector& U = p.U(); label typeId = p.typeId(); scalar& ERot = p.ERot(); label& vibLevel = p.vibLevel(); vector nw = p.normal(); nw /= mag(nw); // Normal velocity magnitude scalar U_dot_nw = U & nw; // Wall tangential velocity (flow direction) vector Ut = U - U_dot_nw*nw; Random& rndGen(cloud_.rndGen()); while (mag(Ut) < SMALL) { // If the incident velocity is parallel to the face normal, no // tangential direction can be chosen. Add a perturbation to the // incoming velocity and recalculate. U = vector ( U.x()*(0.8 + 0.2*rndGen.scalar01()), U.y()*(0.8 + 0.2*rndGen.scalar01()), U.z()*(0.8 + 0.2*rndGen.scalar01()) ); U_dot_nw = U & nw; Ut = U - U_dot_nw*nw; } // Wall tangential unit vector vector tw1 = Ut/mag(Ut); // Info << "tw1 = " << tw1 << endl; // Other tangential unit vector vector tw2 = nw^tw1; const scalar& T = temperature_; scalar mass = cloud_.constProps(typeId).mass(); scalar rotationalDof = cloud_.constProps(typeId).rotationalDegreesOfFreedom(); scalar vibrationalDof = cloud_.constProps(typeId).vibrationalDegreesOfFreedom(); scalar characteristicVibrationalTemperature = cloud_.constProps(typeId).thetaV(); const scalar& alphaT = tangentialAccommodationCoefficient_*(2.0 - tangentialAccommodationCoefficient_); const scalar& alphaN = normalAccommodationCoefficient_; const scalar& alphaR = rotationalEnergyAccommodationCoefficient_; const scalar& alphaV = vibrationalEnergyAccommodationCoefficient_; scalar mostProbableVelocity = sqrt(2.0*physicoChemical::k.value()*T/mass); //normalising the incident velocities vector normalisedTangentialVelocity = Ut/mostProbableVelocity; scalar normalisedNormalVelocity = U_dot_nw/mostProbableVelocity; //normal random number components scalar thetaNormal = 2.0*pi*rndGen.scalar01(); scalar rNormal = sqrt(-alphaN*log(rndGen.scalar01())); //tangential random number components scalar thetaTangential1 = 2.0*pi*rndGen.scalar01(); scalar rTangential1 = sqrt(-alphaT*log(rndGen.scalar01())); scalar thetaTangential2 = 2.0*pi*rndGen.scalar01(); scalar rTangential2 = sqrt(-alphaT*log(rndGen.scalar01())); //selecting the reflected thermal velocities scalar normalisedIncidentTangentialVelocity1 = mag(normalisedTangentialVelocity); scalar um = sqrt(1.0-alphaN)*normalisedNormalVelocity; scalar normalVelocity = sqrt( (rNormal*rNormal) + (um*um) + 2.0*rNormal*um*cos(thetaNormal) ); scalar tangentialVelocity1 = (sqrt(1.0 - alphaT)*mag(normalisedIncidentTangentialVelocity1) + rTangential1*cos(thetaTangential1)); scalar tangentialVelocity2 = rTangential1*sin(thetaTangential1); U = mostProbableVelocity *( tangentialVelocity1*tw1 + tangentialVelocity2*tw2 - normalVelocity*nw ); if( (p.position().x() > 0.002) && ( p.position().x() < 0.0022) ) { if(Pstream::parRun()) { Pout << "Scattering angle, 0 mm = " << atan(U.y()/U.x()) << endl; } else { scalar angle=0; if((tangentialVelocity1*tw1).x()>0) angle = acos( ( (normalVelocity*nw + tangentialVelocity1*tw1) & tangentialVelocity1*tw1 )/mag((normalVelocity*nw+tangentialVelocity1*tw1) * tangentialVelocity1*tw1) ); if((tangentialVelocity1*tw1).x()<0) angle = acos( ( (normalVelocity*nw - tangentialVelocity1*tw1) & tangentialVelocity1*tw1 )/mag((normalVelocity*nw+tangentialVelocity1*tw1) * tangentialVelocity1*tw1) ); Info << "Scattering angle, 0 mm = " << angle << endl; } } if( (p.position().x() > 0.0068) && ( p.position().x() < 0.0072 ) ) { if(Pstream::parRun()) { Pout << "Scattering angle, 5 mm = " << atan(U.y()/U.x()) << endl; } else { scalar angle=0; if((tangentialVelocity1*tw1).x()>0) angle = acos( ( (normalVelocity*nw + tangentialVelocity1*tw1) & tangentialVelocity1*tw1 )/mag((normalVelocity*nw+tangentialVelocity1*tw1) * tangentialVelocity1*tw1) ); if((tangentialVelocity1*tw1).x()<0) angle = acos( ( (normalVelocity*nw - tangentialVelocity1*tw1) & tangentialVelocity1*tw1 )/mag((normalVelocity*nw+tangentialVelocity1*tw1) * tangentialVelocity1*tw1) ); Info << "Scattering angle, 5 mm = " << angle << endl; } } vector uWallNormal = (velocity_ & nw) * nw; vector uWallTangential1 = (velocity_ & tw1) * tw1; vector uWallTangential2 = (velocity_ & tw2) * tw2; vector UNormal = ((U & nw) * nw) + uWallNormal*alphaN; vector UTangential1 = (U & tw1) * tw1 + uWallTangential1*alphaT; vector UTangential2 = (U & tw2) * tw2 + uWallTangential2*alphaT; U = UNormal + UTangential1 + UTangential2; //selecting rotational energy, this is Lord's extension to rotational degrees of freedom if(rotationalDof == 2) { scalar om = sqrt( (ERot*(1.0 - alphaR)) / (physicoChemical::k.value()*T)); scalar rRot = sqrt(-alphaR*(log(max(1.0 - rndGen.scalar01(), VSMALL)))); scalar thetaRot = 2.0*pi*rndGen.scalar01(); ERot = physicoChemical::k.value()*T*((rRot*rRot) + (om*om) + (2.0*rRot*om*cos(thetaRot))); } if(rotationalDof == 3) //polyatomic case, see Bird's DSMC2.FOR code { scalar X = 0.0; scalar A = 0.0; do { X = 4.0*rndGen.scalar01(); A = 2.7182818*X*X*exp(-(X*X)); } while (A < rndGen.scalar01()); scalar om = sqrt( (ERot*(1.0 - alphaR)) / (physicoChemical::k.value()*T)); scalar rRot = sqrt(-alphaR)*X; scalar thetaRot = 2.0*rndGen.scalar01() - 1.0; ERot = physicoChemical::k.value()*T*((rRot*rRot) + (om*om) + (2.0*rRot*om*cos(thetaRot))); } // //selecting vibrational energy, this is lord's extension to vibrational degrees of freedom // // if(vibrationalDof > VSMALL) // { // scalar EVibStar = -log(1.0 - rndGen.scalar01() + rndGen.scalar01()*exp(-characteristicVibrationalTemperature*physicoChemical::k.value())); // // EVib += EVibStar; // // scalar vm = sqrt(1.0-alphaV)*sqrt(EVib); // // scalar thetaVib = 2.0*pi*rndGen.scalar01(); // // scalar rVib = sqrt(-alphaV*log(rndGen.scalar01())); // // EVib = ( // (rVib*rVib) // + (vm*vm) // + 2.0*rVib*vm*cos(thetaVib) // ); // // label iPost = EVib / (characteristicVibrationalTemperature*physicoChemical::k.value()); //post interaction vibrational quantum level // // EVib = iPost * characteristicVibrationalTemperature*physicoChemical::k.value(); // } // EVib = cloud_.equipartitionVibrationalEnergy(T, vibrationalDof, typeId); measurePropertiesAfterControl(p, 0.0); }