Ejemplo n.º 1
0
void Fi_mh(double * Ui, double * Uimo, double * Fimh, double * alphas, double Pi, double Pimo){
  double Fi[3], Fimo[3];//double  Fhll[3];
  Flux(Ui, Fi, Pi); Flux(Uimo, Fimo, Pimo);
  double alphap = alphapm(Ui, Uimo, 1, Pi, Pimo);
  double alpham = alphapm(Ui, Uimo, -1, Pi, Pimo);
  alphas[0] = alphap; alphas[1] = alpham;   
  int i; for(i=0;i<3;++i){
    Fimh[i] = (alphap*Fimo[i] + alpham*Fi[i] - alphap*alpham*(Ui[i]-Uimo[i]))/(alphap+alpham);
  }
}
Ejemplo n.º 2
0
void Fi_mh(double * Ui, double * Uimo, double * Fimh, double * alphas, double Pi, double Pimo){
  double Fi[3], Fimo[3];//double  Fhll[3];
  Flux(Ui, Fi, Pi); Flux(Uimo, Fimo, Pimo);
  double alphap = alphapm(Ui, Uimo, 1, Pi, Pimo);
  double alpham = alphapm(Ui, Uimo, -1, Pi, Pimo);
  //printf("alpha=%f  %f  Pi = %f\n", alphap, alpham, Pi);
  alphas[0] = alphap; alphas[1] = alpham; 
  int i; for(i=0;i<3;++i){
    Fimh[i] = (alphap*Fimo[i] + alpham*Fi[i] - alphap*alpham*(Ui[i]-Uimo[i]))/(alphap+alpham);
  }
  //printf("Fimh = %f\n", Fimh[0], Fimh[1], Fimh[2]); 
}
 Weno(int _size,double _L,double FluxParams[]): size(_size),h1(-1./(_L/size))
 {
   F=Flux(FluxParams);
   // 
   reconstructed=std::make_unique<double[]>(2*size);
   numflux=std::make_unique<double[]>(size);
 }
 Weno(int _size,double _L,double FluxParams[]): size(_size),h1(-1./(_L/size))
 {
   F=Flux(FluxParams);
   // 
   reconstructed=std::make_unique<double[]>(2*size+8);
   InC=std::make_unique<double[]>(size+4);
   work=std::make_unique<double[]>(size+2);
   
 }
Ejemplo n.º 5
0
void CalculateRezidual(Grid& g, Vec u, 
		       Vec r) {
  Vec uLoc, rLoc;
  const double *ul;
  double *rl;
  VecGhostGetLocalForm(u, &uLoc);  
  VecGetArrayRead(uLoc, &ul);

  VecGhostGetLocalForm(r, &rLoc);
  VecSet(rLoc, 0.0);
  VecGetArray(rLoc, &rl);


  for (auto f: g.internalFaces()) {
    double flux = Flux( ul[f.owner], ul[f.neighbour], f.s);
    rl[f.owner] -= flux;
    rl[f.neighbour] += flux;
  }

  for (auto bnd: g.boundaryPatches()) {
    double ub = 0;
    if (bnd.first == BND_BOTTOM) ub = 1;
    
    for (auto f: bnd.second) {
      rl[f.owner] -= Flux( ul[f.owner], ub, f.s);
    }
  }


  VecRestoreArray(rLoc, &rl);
  VecGhostRestoreLocalForm(r, &rLoc);
  VecRestoreArrayRead(uLoc, &ul);
  VecGhostRestoreLocalForm(u, &uLoc);

  VecGhostUpdateBegin(r,ADD_VALUES,SCATTER_REVERSE);
  VecGhostUpdateEnd(r,ADD_VALUES,SCATTER_REVERSE);
  
  
  VecGetArray(r, &rl);
  for (size_t i=0; i<g.cells().size(); i++) rl[i] /= g.cells()[i].vol;
  VecRestoreArray(r, &rl);
}
Ejemplo n.º 6
0
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
flux
(
    const surfaceScalarField& phi,
    const tmp<GeometricField<Type, fvPatchField, volMesh>>& tvf
)
{
    tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> Flux
    (
        fvc::flux(phi, tvf())
    );
    tvf.clear();
    return Flux;
}
Ejemplo n.º 7
0
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
flux
(
    const tmp<surfaceScalarField>& tphi,
    const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
    tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> Flux
    (
        fvc::flux(tphi(), vf)
    );
    tphi.clear();
    return Flux;
}
Ejemplo n.º 8
0
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
flux
(
    const tmp<surfaceScalarField>& tphi,
    const tmp<GeometricField<Type, fvPatchField, volMesh>>& tvf,
    const word& name
)
{
    tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> Flux
    (
        fvc::flux(tphi(), tvf(), name)
    );
    tphi.clear();
    tvf.clear();
    return Flux;
}
  void SecondOrderAssocReaction::AddReactionTerms(qdMatrix      *CollOptr,
    molMapType    &isomermap,
    const double rMeanOmega)
  {
    // Get densities of states of the adduct for detailed balance.
    vector<double> pdtDOS;
    m_pdt1->getDOS().getGrainDensityOfStates(pdtDOS) ;

    // Locate isomers in system matrix.
    const int pdtLoc = isomermap[m_pdt1] ;
    const int jj     = (*m_sourceMap)[get_pseudoIsomer()] ;

    // Get equilibrium constant.
    const qd_real Keq = qd_real(calcEquilibriumConstant()) ;

    // Get Boltzmann distribution for detailed balance.
    vector<double> adductPopFrac ; // Population fraction of the adduct
    const int pShiftedGrains(m_pdt1->getColl().reservoirShift());
    m_pdt1->getColl().normalizedGrnBoltzmannDistribution(adductPopFrac) ;

    qd_real DissRateCoeff(0.0), qdMeanOmega(rMeanOmega) ;

    const int pdtRxnOptPos(pdtLoc - pShiftedGrains);
    const int colloptrsize = m_pdt1->getColl().get_colloptrsize() + pShiftedGrains ;
    const int reverseThreshE = get_EffGrnRvsThreshold();
    const int fluxStartIdx = get_fluxFirstNonZeroIdx();

    // Note: reverseThreshE will always be greater than pShiftedGrains here.

	// In following factors 2.0 and 4.0 appear. These arise from the the Taylor
	// expansion of the non-linear term about the the equilibrium point. 

    for ( int i = reverseThreshE, j = fluxStartIdx; i < colloptrsize; ++i, ++j) {
      int ii(pdtRxnOptPos + i) ;
      int kk (i - pShiftedGrains);
      qd_real Flux(m_GrainFlux[j]), dos(pdtDOS[i]), addPop(adductPopFrac[kk]) ;
      (*CollOptr)[ii][ii] -= qdMeanOmega * Flux / dos ;                                 // Loss of the adduct to the source
      (*CollOptr)[jj][ii]  = qdMeanOmega * Flux * qd_real(2.0) * sqrt(Keq*addPop)/dos ; // Reactive gain of the source
      (*CollOptr)[ii][jj]  = (*CollOptr)[jj][ii] ;                                      // Reactive gain (symmetrization)
      DissRateCoeff       += Flux * addPop / dos;
    }
    (*CollOptr)[jj][jj] -= qd_real(4.0) * qdMeanOmega * DissRateCoeff * Keq ;           // Loss of the source from detailed balance.
  }
Ejemplo n.º 10
0
void SpatialMesh::Update_boundary(AngularMesh& Angle){
	bd.resize(Angle.ns);
	for (register int j = 0; j < Angle.ns; j++){
		bd[j].resize(nt);
		for (register int k = 0; k < nt; k++){
			bd[j][k].resize(9);
			for (int l = 0 ; l < 9 ; l++){
				bd[j][k][l] = -1;
			}
		}
	}
	bd2.resize(Angle.ns);
	for (register int j = 0; j < Angle.ns; j++){
		bd2[j].resize(nt);
		for (register int k = 0; k < nt; k++){
			bd2[j][k].resize(3);
		}
	}
	for (register int j = 0 ; j < Angle.ns; j++){
		Flux(nt, Angle.a[j], p, p2, t, bd[j], bd2[j], so2);
	}
}
Ejemplo n.º 11
0
Colour Raytracer::Trace(const Ray& ray, RandomGenerator* random, int depth, int depth2, std::list<IMedium*>& mediumList)
{
	if(depth >= this->maxIterations)
		return Vec3(0,0,0);

	// First find intersection with closes geometry.
	IntersectResult result;
	geometry->Intersect(ray, result);

	// First depth2=0, we also include "singular light geometry"
	if(depth2 == 0 && this->singularLightGeometry)
		singularLightGeometry->Intersect(ray, result);

	if(result.distance >= std::numeric_limits<Scalar>::max())
		return Vec3(0,0,0); //< Return "sky" radiance

	// Calculate position of intersection.
	
	Vec3 position = result.distance * ray.direction + ray.origin;
	Vec3 cameraDirection = -ray.direction;

	// Check for interaction with medium (scaterring)
	ColourScalar scateringWeight;
	Vec3 scatteringPos, scatteringDir;
	if(ray.medium->SampleScattering(ray.origin, result.normal, position, random, scateringWeight,
		scatteringPos, scatteringDir))
	{
		Ray newRay(scatteringPos, scatteringDir);
		newRay.medium = ray.medium;
		return scateringWeight.CMultiply(Trace(newRay, random, depth+1, depth2, mediumList));
	}


	// Now calculate mediums.
	bool isInsideMedium = cameraDirection * result.normal < 0;
	IMedium* insideMedium, *outsideMedium;
	if(isInsideMedium)
	{
		// FIXME: sometimes due to numerical errors, we ignore those hits (alternative - set to vacuum).
		if(mediumList.size() == 0)
			return Vec3(0,0,0);
		outsideMedium = mediumList.back();
		insideMedium = ray.medium;
	} else {
		outsideMedium = ray.medium;
		insideMedium = result.material->insideMedium;
	}

	// Compute radiance of point.
	Vec3 L(0,0,0);

	// 1) self radiance
	if(SELF_LIGHTNING_BIT(depth, depth2) && result.material->surfaceLight != 0)
		L = SELF_LIGHTNING_MASK(depth, depth2, result.material->surfaceLight->Radiance(position, cameraDirection, result.normal));
	
	// Early exit for non-reflective materials. This is useful for singular lights.
	if(result.material->bsdf == 0)
		return scateringWeight.CMultiply(L);
	SamplingType samplingType = result.material->bsdf->GetSamplingType(cameraDirection, result.normal);
	

	// 2) radiance from singular sources
	if(DIRECT_LIGHTNING_BIT(depth, depth2) && ((samplingType & Singular) != 0))
	{
		for(std::vector<ISingularLight*>::iterator i = lights.begin(); i != lights.end(); i++)
		{
			ISingularLight* light = *i;
			Vec3 towardsLightDirection;

			// We can use radiance at position for point lights (no translate).
			Vec3 Li = light->Radiance(position, towardsLightDirection, geometry);

			// Early exit for shadowed lights (no BRDF execution) && when backfacing lights.
			if(Li.x == 0 && Li.y == 0 && Li.z == 0)
				continue;
			 
			// Weights with cosine.
			Vec3 t = (result.normal * towardsLightDirection)*Li.CMultiply(result.material->bsdf->BSDF(position, result.normal,
				 cameraDirection, towardsLightDirection, result.materialData, insideMedium, outsideMedium));
			L += DIRECT_LIGHTNING_MASK(depth, depth2, t);
		}
	}
	// 3) caustics map lightning
	if(PHOTONMAP_CAUSTICS_BIT(depth, depth2) && this->causticsMap)
	{
		std::vector<Photon*> photons;
		causticsMap->FindInRange(position, this->causticsPhotonMapGatherRadius, photons);

		// We estimate radiance at the point.
		Vec3 Flux(0,0,0);
		for(std::vector<Photon*>::iterator i = photons.begin(); i != photons.end(); i++)
		{
			Photon* p = *i;

			// Cull backfacings.
			if(p->outDirection * result.normal < 0)
				continue;

			Flux += p->power.CMultiply((result.normal * p->outDirection) * result.material->bsdf->BSDF(position, result.normal, p->outDirection, cameraDirection, result.materialData,
				insideMedium, outsideMedium));
		}

		Vec3 t = Flux / (PI*this->causticsPhotonMapGatherRadius*this->causticsPhotonMapGatherRadius);

		L += PHOTONMAP_CAUSTICS_MASK(depth, depth2, t);
	}

	// Calculate number of samples
	int numberOfSamples = std::min(result.material->bsdf->GetMaxNumberOfSamples(cameraDirection, result.normal), 
		(int)(this->secondaryRays * exp(-secondaryRayDecay*depth2)));

	bool isPerfectReflection = numberOfSamples <= this->gatherIterationThreeshold;	//< This will only allow bigger iteration depth.

	// 4a) indirect photon map rendering (it is either this or hemisphere integration), reflection is still handled with
	// normal raytracing
	if(PHOTONMAP_GLOBAL_BIT(depth, depth2) && !isPerfectReflection && this->globalMap)
	{
		std::vector<Photon*> photons;
		globalMap->FindInRange(position, this->globalPhotonMapGatherRadius, photons);

		// We estimate radiance at the point.
		Vec3 Flux(0,0,0);
		for(std::vector<Photon*>::iterator i = photons.begin(); i != photons.end(); i++)
		{
			Photon* p = *i;

			// Cull backfacings.
			if(p->outDirection * result.normal < 0)
				continue;

			Flux += p->power.CMultiply((result.normal * p->outDirection) * result.material->bsdf->BSDF(position, result.normal, p->outDirection, cameraDirection, result.materialData,
				insideMedium, outsideMedium));
		}

		Vec3 t = Flux / (PI*this->globalPhotonMapGatherRadius*this->globalPhotonMapGatherRadius);

		L += PHOTONMAP_GLOBAL_MASK(depth, depth2, t);

		// We skip through
		return scateringWeight.CMultiply(L);
	}


	// 4b) integrated radiance over hemisphere
	if((samplingType & MultipleSample) == 0 || INDIRECT_LIGHTNING_BIT(depth, depth2) == false)
		return scateringWeight.CMultiply(L);

	
	if(depth2 < this->maxGatherIterations || isPerfectReflection)
	{
		// If perfect reflection, we need only one ray to approximate.
		for(int i = 0; i < numberOfSamples; i++)
		{
			Vec3 newDirection;
			ColourScalar S = result.material->bsdf->Sample(i, numberOfSamples, position, result.normal, 
				cameraDirection, random, result.materialData, insideMedium, outsideMedium, newDirection); 

			// Trace new ray.
			Ray newRay(position, newDirection);
			bool needsPop = false, needsPush = false;
			Scalar translateInwards = -1;
			if(isInsideMedium)
			{
				// In-Out combination
				if(newDirection * result.normal > 0)
				{
					newRay.medium = mediumList.back();
					mediumList.pop_back();
					needsPush = true;
					translateInwards = 1;
				}
				// In-In combination
				else
					newRay.medium = ray.medium;
			}
			else {
				// Out-out combination
				if(newDirection * result.normal > 0)
					newRay.medium = ray.medium;
				else
				{
					newRay.medium = result.material->insideMedium;
					mediumList.push_back(ray.medium);
					needsPop = true;
					translateInwards = 1;
				}
			}

			// Translation of ray position so the whole solid angle can be sampled (also in corners)
			newRay.origin = newRay.origin + (translateInwards * this->hitTranslate) * ray.direction;

			ColourScalar newL = Trace(newRay, random, depth+1, depth2 + (isPerfectReflection ? 0 : 1), mediumList);

			// Undo medium list to prev state
			if(needsPush)
				mediumList.push_back(newRay.medium);
			if(needsPop)
				mediumList.pop_back();

			// NaN check (FIXME: must get rid of it and find the source).
			if(newL.x != newL.x || newL.y != newL.y || newL.z != newL.z)
			{
				continue;
			}

			// Add already weighted result to intensity.
			Vec3 t = S.CMultiply(newL);
			L += INDIRECT_LIGHTNING_MASK(depth,depth2,t);
		}
	}

	return scateringWeight.CMultiply(L);

}