Ejemplo n.º 1
0
void Bracket_Pairs(const double &i_dSearch_Value, const XDATASET &i_cAbundance_Data,const XDATASET &i_cDensity_Data, const XDATASET &i_cHe3_Data,const XDATASET &i_cHyd_Data, const LINE_DATA & i_cLine_Data, const double & i_dFluid_Temp, const double & i_dTime, const double & i_dTime_Ref,unsigned int * o_uiLow_Index_Values, double * o_dLow_Interpolation_Values, unsigned int * o_uiHigh_Index_Values, double * o_dHigh_Interpolation_Values, unsigned int i_uiMax_Values, unsigned int &o_uiNum_Pairs, bool &o_bMore_Points)
{
	unsigned int uiNum_Points = i_cAbundance_Data.GetNumElements() - 1;
	unsigned int uiI;

	o_uiNum_Pairs = 0;
	double	dLow = Optical_Depth(ComputeDensity(0, i_cAbundance_Data, i_cDensity_Data, i_cHe3_Data ,i_cHyd_Data),i_cLine_Data,i_dFluid_Temp,i_dTime,i_dTime_Ref);
	o_bMore_Points = false;

//	printf("----------------\n Search: %.3f\n",i_dSearch_Value);
	uiI = 0;
	while (uiI < uiNum_Points)
	{
		double	dPrev = dLow;
		if (uiI != 0)
		{
			dPrev = Optical_Depth(ComputeDensity(uiI - 1, i_cAbundance_Data, i_cDensity_Data, i_cHe3_Data ,i_cHyd_Data), i_cLine_Data, i_dFluid_Temp, i_dTime, i_dTime_Ref);
		}

		if (dLow > i_dSearch_Value)
		{
			if (o_uiNum_Pairs < i_uiMax_Values)
			{
				o_uiLow_Index_Values[o_uiNum_Pairs] = uiI;
				if (uiI != 0)
					o_dLow_Interpolation_Values[o_uiNum_Pairs] = (i_dSearch_Value - dLow) / (dPrev - dLow);
				else
					o_dLow_Interpolation_Values[o_uiNum_Pairs] = 0.0;
			}
			else 
				o_bMore_Points = true;
			
			uiI++;
			while (Optical_Depth(i_cAbundance_Data.GetElement(1,uiI) * i_cDensity_Data.GetElement(1,uiI),i_cLine_Data,i_dFluid_Temp,i_dTime,i_dTime_Ref) > (i_dSearch_Value) && uiI < uiNum_Points)
			{
				uiI++;
			}
			dLow = Optical_Depth(ComputeDensity(uiI, i_cAbundance_Data, i_cDensity_Data, i_cHe3_Data ,i_cHyd_Data), i_cLine_Data, i_dFluid_Temp, i_dTime, i_dTime_Ref);
			dPrev = Optical_Depth(ComputeDensity(uiI - 1, i_cAbundance_Data, i_cDensity_Data, i_cHe3_Data ,i_cHyd_Data), i_cLine_Data, i_dFluid_Temp, i_dTime, i_dTime_Ref);
			if (o_uiNum_Pairs < i_uiMax_Values)
			{
				o_dHigh_Interpolation_Values[o_uiNum_Pairs] = (i_dSearch_Value - dLow) / (dPrev - dLow);
				o_uiHigh_Index_Values[o_uiNum_Pairs] = uiI - 1;
				o_uiNum_Pairs++;
			}
		}
		uiI++;
		dLow = Optical_Depth(ComputeDensity(uiI, i_cAbundance_Data, i_cDensity_Data, i_cHe3_Data ,i_cHyd_Data), i_cLine_Data, i_dFluid_Temp, i_dTime, i_dTime_Ref);
	}

//	printf("----------------\n");
}
Ejemplo n.º 2
0
void TreatBoundary(float *collide_field, int* flag_field, float *wall_velocity, int xlength){
    int x,nx,y,ny,z,nz,i,step=xlength+2;
    float density,dot_prod;
    
    for(x=0;x<step;x++){
        for(y=0;y<step;y++){
            for(z=0;z<step;z++){
                if(flag_field[x+y*step+z*step*step]!=FLUID){
                    for(i=0;i<Q_LBM;i++){
                        nx=x+LATTICE_VELOCITIES[i][0];
                        ny=y+LATTICE_VELOCITIES[i][1];
                        nz=z+LATTICE_VELOCITIES[i][2];

                        /* We don't need the values outside of our extended domain */
                        if(0<nx && nx<step-1 && 0<ny && ny<step-1 && 0<nz && nz<step-1){
                            if (flag_field[x+y*step+z*step*step]==MOVING_WALL){
                                /* Compute density in the neighbour cell */
                                ComputeDensity(&collide_field[Q_LBM*(nx+ny*step+nz*step*step)],&density);
                                /* Compute dot product */
                                dot_prod=LATTICE_VELOCITIES[i][0]*wall_velocity[0]+
                                        LATTICE_VELOCITIES[i][1]*wall_velocity[1]+
                                        LATTICE_VELOCITIES[i][2]*wall_velocity[2];
                                /* Assign the boudary cell value */
                                collide_field[Q_LBM*(x+y*step+z*step*step)+i]=
                                        collide_field[Q_LBM*(nx+ny*step+nz*step*step)+inv(i)]+
                                        2*LATTICE_WEIGHTS[i]*density*C_S_POW2_INV*dot_prod;
                            }else if(flag_field[x+y*step+z*step*step]==NO_SLIP){
                                collide_field[Q_LBM*(x+y*step+z*step*step)+i]=
                                        collide_field[Q_LBM*(nx+ny*step+nz*step*step)+inv(i)];
                            }
                        }
                    }
                }
            }
        }
    }
}
// This routine simply glues together many of the routines that are already
// written in the Poisson solver library
//
// phi( 1:SubNumPhysNodes       ) is a scalar quantity.  
//
// E1 ( 1:NumElems, 1:kmax2d ) is a vector quantity.
// E2 ( 1:NumElems, 1:kmax2d ) is a vector quantity.
//
// See also: ConvertEfieldOntoDGbasis
void ComputeElectricField( const double t, const mesh& Mesh, const dTensorBC5& q,
    dTensor2& E1, dTensor2& E2)
{

    //
    const int       mx = q.getsize(1);   assert_eq(mx,dogParamsCart2.get_mx());
    const int       my = q.getsize(2);   assert_eq(my,dogParamsCart2.get_my());
    const int NumElems = q.getsize(3);
    const int     meqn = q.getsize(4);
    const int     kmax = q.getsize(5);

    const int space_order = dogParams.get_space_order();

    // unstructured parameters:
    const int kmax2d    = E2.getsize(2);
    const int NumBndNodes  = Mesh.get_NumBndNodes();
    const int NumPhysNodes = Mesh.get_NumPhysNodes();

    // Quick error check
    if( !Mesh.get_is_submesh() )
    {
        printf("ERROR: mesh needs to have subfactor set to %d\n", space_order);
        printf("Go to Unstructured mesh and remesh the problem\n");
        exit(-1);
    }
    const int SubFactor    = Mesh.get_SubFactor();

    assert_eq( NumElems, Mesh.get_NumElems() );

    // -- Step 1: Compute rho -- //
    dTensor3 rho(NumElems, 1, kmax2d );
    void ComputeDensity( const mesh& Mesh, const dTensorBC5& q, dTensor3& rho );
    ComputeDensity( Mesh, q, rho );

    // -- Step 2: Figure out how large phi needs to be
    int SubNumPhysNodes = 0;
    int SubNumBndNodes  = 0;
    switch( dogParams.get_space_order() )
    {
        case 1:
            SubNumPhysNodes = NumPhysNodes;
            SubNumBndNodes  = NumBndNodes;
            break;

        case 2:
            SubNumPhysNodes = Mesh.get_SubNumPhysNodes();
            SubNumBndNodes  = Mesh.get_SubNumBndNodes();
            if(SubFactor!=2)
            {
                printf("\n");
                printf(" Error: for space_order = %i, need SubFactor = %i\n",space_order,2);
                printf("      SubFactor = %i\n",SubFactor);
                printf("\n");
                exit(1);
            }
            break;

        case 3:
            SubNumPhysNodes = Mesh.get_SubNumPhysNodes();
            SubNumBndNodes  = Mesh.get_SubNumBndNodes();
            if(SubFactor!=3)
            {
                printf("\n");
                printf(" Error: for space_order = %i, need SubFactor = %i\n",space_order,3);
                printf("      SubFactor = %i\n",SubFactor);
                printf("\n");
                exit(1);
            }
            break;

        default:
            printf("\n");
            printf(" ERROR in RunDogpack_unst.cpp: space_order value not supported.\n");
            printf("       space_order = %i\n",space_order);
            printf("\n");
            exit(1);
    }

    // local storage:
    dTensor1 rhs(SubNumPhysNodes);
    dTensor1 phi(SubNumPhysNodes);

    // Get Cholesky factorization matrix R
    //
    // TODO - this should be saved earlier in the code rather than reading
    // from file every time we with to run a Poisson solve!
    //
    SparseCholesky R(SubNumPhysNodes);
    string outputdir = dogParams.get_outputdir();
    R.init(outputdir);
    R.read(outputdir);

    // Create right-hand side vector
    void Rhs2D_unst(const int space_order,
            const mesh& Mesh, const dTensor3& rhs_dg,
            dTensor1& rhs);
    Rhs2D_unst(space_order, Mesh, rho, rhs);

    // Call Poisson solver  
    void PoissonSolver2D_unst(const int space_order,
            const mesh& Mesh,
            const SparseCholesky& R,
            const dTensor1& rhs,
            dTensor1& phi,
            dTensor2& E1,
            dTensor2& E2);
    PoissonSolver2D_unst(space_order, Mesh, R, rhs, phi, E1, E2);

    // Compare errors with the exact Electric field:
    //
    void L2Project_Unst(
        const double time,
        const dTensor2* vel_vec,
        const int istart, 
        const int iend, 
        const int QuadOrder, 
        const int BasisOrder_qin,
        const int BasisOrder_auxin,
        const int BasisOrder_fout,
        const mesh& Mesh, 
        const dTensor3* qin, 
        const dTensor3* auxin, 
        dTensor3* fout, 
        void (*Func)(const double t, const dTensor2* vel_vec, const dTensor2&,const dTensor2&,
            const dTensor2&,dTensor2&));

    const int sorder = dogParams.get_space_order();
    dTensor3 qtmp   (NumElems, 2, kmax2d );  qtmp.setall(0.);
    dTensor3 auxtmp (NumElems, 0, kmax2d );
    dTensor3 ExactE (NumElems, 2, kmax2d );
    L2Project_Unst( t, NULL, 1, NumElems, 
        sorder, sorder, sorder, sorder, Mesh, 
        &qtmp, &auxtmp, &ExactE, 
        &ExactElectricField );

    // Compute errors on these two:
    //
    double err = 0.;
    for( int n=1; n <= NumElems; n++ )
    for( int k=1; k <= kmax2d;   k++ )
    {
        err += Mesh.get_area_prim(n)*pow( ExactE.get(n,1,k) - E1.get(n,k), 2 );
        err += Mesh.get_area_prim(n)*pow( ExactE.get(n,2,k) - E2.get(n,k), 2 );
    }
    printf("error = %2.15e\n", err );

}
Ejemplo n.º 4
0
void BroadLineDataCSV(const XDATASET &i_cVelocity_Data, const XDATASET &i_cAbundance_Data,const XDATASET &i_cHe3_Data,const XDATASET &i_cHyd_Data,const XDATASET &i_cDensity_Data, const LINE_DATA & i_cLine_Data, const double & i_dTime_Ref, const char * lpszLineName, const double * i_lpdTemps, unsigned int i_uiNum_Temps, const char * i_lpszFilename_Lines, const char * i_lpszFilename_Specta, const char * i_lpszFilename_OpDepth)
{
#define NUM_VALUES 16

	unsigned int	uiLow_Index_Values[128][NUM_VALUES];
	double			dLow_Interpolation_Values[128][NUM_VALUES];
	unsigned int	uiHigh_Index_Values[128][NUM_VALUES];
	double			dHigh_Interpolation_Values[128][NUM_VALUES];
	double			dVelocity_Values_Low[128][NUM_VALUES];
	double			dVelocity_Values_High[128][NUM_VALUES];
//	double			dVelocity_Values_Report[128][16];
	unsigned int	uiRow_Mapping[128][NUM_VALUES];
	unsigned int	uiNum_Values[128];
	bool			bExcess_Values[128];
	unsigned int	uiMax_Values = 0;
	unsigned int	uiIndex_Max = 0;
	double			dVelocity_Max = 0.0;
//	double			dHV_Lines[128];
//	double			dPS_Lines[128];

	XDATASET		cHV_Line_Data;
		unsigned int uiI, uiJ, uiK, uiTemp;

	FILE * fileSpectra = fopen(i_lpszFilename_Specta,"wt");
	if (!fileSpectra)
	{
		printf("Unable to open file %s for writing.\n",i_lpszFilename_Specta);
		return;
	}
	FILE * fileLines = fopen(i_lpszFilename_Lines,"wt");
	if (!fileLines)
	{
		printf("Unable to open file %s for writing.\n",i_lpszFilename_Lines);
		return;
	}
	FILE * fileOpDepth = fopen(i_lpszFilename_OpDepth,"wt");
	if (!fileOpDepth)
	{
		printf("Unable to open file %s for writing.\n",i_lpszFilename_OpDepth);
		return;
	}

	// allocate and zero the line data
	cHV_Line_Data.Allocate(i_uiNum_Temps * 2,128);
	for (uiI = 0; uiI < 128; uiI++)
	{
		for (uiJ = 0; uiJ < 2 + i_uiNum_Temps * 2; uiJ++)
		{
			cHV_Line_Data.SetElement(uiJ,uiI,0.0);
		}
	}
	unsigned int uiNumVelBins = 128;
	double	dVelocity_Bins[128][128];
//	for (uiI = 0; uiI < 128; uiI++)
//		dVelocity_Bins[uiI] = new double[uiNumVelBins];
	for (uiI = 0; uiI < i_cVelocity_Data.GetNumElements(); uiI++)
	{
		if (dVelocity_Max < i_cVelocity_Data.GetElement(1,uiI))
			dVelocity_Max = i_cVelocity_Data.GetElement(1,uiI);
	}
//		double	dDoppler_Width = sqrt(g_XASTRO.k_dKb * dFluid_Temp / g_XASTRO.k_dmh) / 1.0e9; // in 10,000 km/s units
	double dDoppler_Width = dVelocity_Max / 130.0;
	for (uiTemp = 0; uiTemp < i_uiNum_Temps; uiTemp++)
	{
		double dFluid_Temp = i_lpdTemps[uiTemp];

		for (uiI = 0; uiI < 128; uiI++)
		{
			for (uiJ =0; uiJ < uiNumVelBins; uiJ++)
				dVelocity_Bins[uiI][uiJ] = 1.0;
		}
			
		for (uiI = 0; uiI < 128; uiI++)
		{
			double	dTime = 86500.0 * (uiI + 1)  * 0.25;
	//		printf("%.2f,%.17e",(uiI+1) * 0.25,log10(dTRef * dTRef * dTRef / (dTime * dTime)));
	//		Bracket_Value(1.0,i_cAbundance_Data,i_cDensity_Data, i_cLine_Data, i_dFluid_Temp, dTime, i_dTime_Ref,uiLow_Index_Values[uiI],dLow_Interpolation_Values[uiI],16,uiNum_Values[uiI],bExcess_Values[uiI]);
			Bracket_Pairs(1.0,i_cAbundance_Data,i_cDensity_Data, i_cHe3_Data, i_cHyd_Data, i_cLine_Data, dFluid_Temp, dTime, i_dTime_Ref,uiLow_Index_Values[uiI],dLow_Interpolation_Values[uiI],uiHigh_Index_Values[uiI],dHigh_Interpolation_Values[uiI],NUM_VALUES,uiNum_Values[uiI],bExcess_Values[uiI]);
			Velocity_Lookup(i_cVelocity_Data,uiLow_Index_Values[uiI],dLow_Interpolation_Values[uiI],uiNum_Values[uiI],dVelocity_Values_Low[uiI]);
			Velocity_Lookup(i_cVelocity_Data,uiHigh_Index_Values[uiI],dHigh_Interpolation_Values[uiI],uiNum_Values[uiI],dVelocity_Values_High[uiI]);
			for (uiJ = 0; uiJ < uiNum_Values[uiI]; uiJ++)
			{
				// fill 'synthetic spectra' data
				unsigned int uiLow = dVelocity_Values_Low[uiI][uiJ] / dDoppler_Width;
				unsigned int uiHigh = dVelocity_Values_High[uiI][uiJ] / dDoppler_Width + 1;
				if (uiLow > 0)
					dVelocity_Bins[uiI][uiLow - 1] *= 0.5;
				if (uiHigh < (uiNumVelBins - 1))
					dVelocity_Bins[uiI][uiHigh + 1] *= 0.5;
				for (uiK = uiLow; uiK <= uiHigh; uiK++)
				{
					dVelocity_Bins[uiI][uiK] = 0.0;
				}
				// Fill HV line and PS line data
				if (i_cHe3_Data.GetElement(1,uiHigh_Index_Values[uiI][uiJ]) > 1.0e-9) // shell
				{
					if (cHV_Line_Data.GetElement(uiTemp * 2    ,uiI) < dVelocity_Values_High[uiI][uiJ])
						cHV_Line_Data.SetElement(uiTemp * 2    ,uiI,dVelocity_Values_High[uiI][uiJ]);
				}
				if (i_cHe3_Data.GetElement(1,uiHigh_Index_Values[uiI][uiJ]) < 1.0e-9 && i_cHyd_Data.GetElement(1,uiHigh_Index_Values[uiI][uiJ]) < 1.0e-9) // not in shell
				{
					if (cHV_Line_Data.GetElement(uiTemp * 2 + 1,uiI) < dVelocity_Values_High[uiI][uiJ])
						cHV_Line_Data.SetElement(uiTemp * 2 + 1,uiI,dVelocity_Values_High[uiI][uiJ]);
				}
			}
		}

		// output 'synthetic spectra' data

		fprintf(fileSpectra,"-----,-----,-----,-----,%s,-----,-----,-----,-----\n-----,-----,-----,-----,%.0f K,-----,-----,-----,-----\nDay,logTau",lpszLineName,dFluid_Temp);
		for (uiI = 0; uiI < uiNumVelBins; uiI++)
		{
			fprintf(fileSpectra,",%.0f",(uiI + 0.5) * dDoppler_Width * 10000.0);
		}
		fprintf(fileSpectra,"\n");

		for (uiI = 0; uiI < 128; uiI++)
		{
			double	dTime = (uiI + 1)  * 0.25;
			fprintf(fileSpectra,"%.2f,%.17e",dTime,log10(i_dTime_Ref * i_dTime_Ref * i_dTime_Ref / (dTime * dTime)));
			for (uiJ = 0; uiJ < uiNumVelBins; uiJ++)
			{
				fprintf(fileSpectra,",%.2f",dVelocity_Bins[uiI][uiJ]);
			} 
			fprintf(fileSpectra,"\n");
		}
	}
	fclose(fileSpectra);
	fileSpectra = NULL;


	dDoppler_Width = 6.0 / 130.0; // use smaller range for the synthetic spectra
	fprintf(fileOpDepth,"-----,-----,-----,-----,%s,-----,-----,-----,-----\n",lpszLineName);
	for (uiI = 0; uiI < i_uiNum_Temps; uiI++)
	{
		double dFluid_Temp = i_lpdTemps[uiI];
		double dOpDepth[128];
		fprintf(fileOpDepth,"-----,-----,-----,-----,%.0f K,-----,-----,-----,-----\nDay",dFluid_Temp);
		for (uiJ = 0; uiJ < uiNumVelBins; uiJ++)
		{
			fprintf(fileOpDepth,",%.0f",(uiJ + 0.5) * dDoppler_Width * 10000.0);
		}
		fprintf(fileOpDepth,"\n");
		for (uiJ = 0; uiJ < 8; uiJ++)
		{
//			uiJ = 0;
			memset(dOpDepth,0,sizeof(dOpDepth));
			double	dTime = uiJ * 4 + 1;//  * 0.25;
			for (uiK = 0; uiK < i_cVelocity_Data.GetNumElements(); uiK++)
			{
				unsigned int uiBin = i_cVelocity_Data.GetElement(1,uiK) / dDoppler_Width;
//				printf("%.0f,%.0f,%.1e\n",dFluid_Temp,i_cVelocity_Data.GetElement(1,uiK) * 10000.0,Optical_Depth(ComputeDensity(uiK, i_cAbundance_Data, i_cDensity_Data, i_cHe3_Data ,i_cHyd_Data), i_cLine_Data, dFluid_Temp, dTime, i_dTime_Ref));
				if (uiBin < 128)
				{
					double dOpDepthLcl = Optical_Depth(ComputeDensity(uiK, i_cAbundance_Data, i_cDensity_Data, i_cHe3_Data ,i_cHyd_Data), i_cLine_Data, dFluid_Temp, dTime, i_dTime_Ref);
					dOpDepth[uiBin] += dOpDepthLcl;
					if (dOpDepthLcl < 0.0)
						printf("Strange value on day %i, vel = %.0f for %s\n",(uiJ + 1) * 4,i_cVelocity_Data.GetElement(1,uiK),lpszLineName);
				}
			}
			fprintf(fileOpDepth,"%.2f",dTime);
			for (uiK = 0; uiK < 128; uiK++)
			{
				double dTransmission = 0.0;
				if (dOpDepth[uiK] < 700.0)
					dTransmission = exp(-dOpDepth[uiK]);
				if (dTransmission > 1.0)
					printf("Strange value on day %i, vel = %.0f for %s\n",(uiJ + 1) * 4,(uiK + 0.5) * dDoppler_Width * 10000.0,lpszLineName);
				fprintf(fileOpDepth,",%.17e",dTransmission);
			}
			fprintf(fileOpDepth,"\n");
		}
	}
	fclose(fileOpDepth);
			


	fprintf(fileLines,"-----,-----,-----,-----,%s,-----,-----,-----,-----\nDay,log Tau",lpszLineName);
	for (uiJ = 0; uiJ < i_uiNum_Temps; uiJ++)
		fprintf(fileLines,",V(HV:%.0f K) [km/s],V(PS:%.0f K) [km/s]",i_lpdTemps[uiJ],i_lpdTemps[uiJ]);
	fprintf(fileLines,"\n");

	for (uiI = 0; uiI < 128; uiI++)
	{
		double	dTime = (uiI + 1)  * 0.25;
		fprintf(fileLines,"%.2f,%.17e",dTime,log10(i_dTime_Ref * i_dTime_Ref * i_dTime_Ref / (dTime * dTime)));
		for (uiJ = 0; uiJ < i_uiNum_Temps; uiJ++)
		{
			if (cHV_Line_Data.GetElement(uiJ * 2   ,uiI) > 0.0)
				fprintf(fileLines,",%.17e",cHV_Line_Data.GetElement(uiJ * 2   ,uiI) * 10000.0);
			else
				fprintf(fileLines,",");
			if (cHV_Line_Data.GetElement(uiJ * 2 + 1,uiI) > 0.0)
				fprintf(fileLines,",%.17e",cHV_Line_Data.GetElement(uiJ * 2 + 1,uiI) * 10000.0);
			else
				fprintf(fileLines,",");
		}
		fprintf(fileLines,"\n");
	}

	fclose(fileLines);

	for (uiI = 0; uiI < 128; uiI++)
	{
		if (bExcess_Values[uiI])
		{
			printf("Warning: Excess Values\n");
			uiI = 128;
		}
	}

//	for (uiI = 0; uiI < 128; uiI++)
//	{
//		delete dVelocity_Bins[uiI];
//	}
#undef NUM_VALUES
}