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); } }
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); }
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); }
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; }
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; }
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. }
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); } }
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); }