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);
    }
예제 #2
0
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;
}
예제 #3
0
파일: random.cpp 프로젝트: Mirocow/balancer
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;
}
예제 #4
0
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);
    }
}
예제 #5
0
	// 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);
	}
예제 #6
0
파일: larson.cpp 프로젝트: 3Hren/libcds
        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;
}
예제 #9
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;
	}

}
예제 #13
0
        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);
    }
예제 #17
0
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);
}