Пример #1
0
void RemovalState::Update(Map& map, NGridType& grid, GridInfo& info, uint32 diff) const
{
    if (!info.getUnloadLock())
    {
        info.UpdateTimeTracker(diff);
        if (info.getTimeTracker().Passed() && !map.UnloadGrid(grid, false))
        {
            TC_LOG_DEBUG("maps", "Grid[%u, %u] for map %u differed unloading due to players or active objects nearby", grid.getX(), grid.getY(), map.GetId());
            map.ResetGridExpiry(grid);
        }
    }
}
Пример #2
0
void RemovalState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 t_diff) const
{
    if (!info.getUnloadLock())
    {
        info.UpdateTimeTracker(t_diff);
        if (info.getTimeTracker().Passed())
        {
            if (!m.UnloadGrid(grid, false))
            {
                sLog->outDebug(LOG_FILTER_MAPS, "Grid[%u, %u] for map %u differed unloading due to players or active objects nearby", grid.getX(), grid.getY(), m.GetId());
                m.ResetGridExpiry(grid);
            }
        }
    }
}
Пример #3
0
void
RemovalState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 &x, const uint32 &y, const uint32 &t_diff) const
{
    if(!info.getUnloadLock())
    {
        info.UpdateTimeTracker(t_diff);
        if( info.getTimeTracker().Passed() )
        {
            if( !m.UnloadGrid(x, y, false) )
            {
                DEBUG_LOG("Grid[%u,%u] for map %u differed unloading due to players or active objects nearby", x, y, m.GetId());
                m.ResetGridExpiry(grid);
            }
        }
    }
}
Пример #4
0
void ActiveState::Update(Map &m, NGridType &grid, GridInfo & info,
        const uint32 &x, const uint32 &y, const uint32 &t_diff) const {
    // Only check grid activity every (grid_expiry/10) ms, because it's really useless to do it every cycle
    info.UpdateTimeTracker(t_diff);
    if (info.getTimeTracker().Passed()) {
        if (grid.ActiveObjectsInGrid() == 0 && !m.ActiveObjectsNearGrid(x, y)) {
            ObjectGridStoper stoper(grid);
            stoper.StopN();
            grid.SetGridState(GRID_STATE_IDLE);
            sLog->outDebug(LOG_FILTER_MAPS,
                    "Grid[%u, %u] on map %u moved to IDLE state", x, y,
                    m.GetId());
        } else {
            m.ResetGridExpiry(grid, 0.1f);
        }
    }
}
Пример #5
0
void ActiveState::Update(Map& map, NGridType& grid, GridInfo&  info, uint32 diff) const
{
    // Only check grid activity every (grid_expiry/10) ms, because it's really useless to do it every cycle
    info.UpdateTimeTracker(diff);
    if (info.getTimeTracker().Passed())
    {
        if (!grid.GetWorldObjectCountInNGrid<Player>() && !map.ActiveObjectsNearGrid(grid))
        {
            ObjectGridStoper worker;
            TypeContainerVisitor<ObjectGridStoper, GridTypeMapContainer> visitor(worker);
            grid.VisitAllGrids(visitor);
            grid.SetGridState(GRID_STATE_IDLE);
            TC_LOG_DEBUG("maps", "Grid[%u, %u] on map %u moved to IDLE state", grid.getX(), grid.getY(), map.GetId());
        }
        else
            map.ResetGridExpiry(grid, 0.1f);
    }
}
Пример #6
0
void
ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, const uint32 &y, const uint32 &t_diff) const
{
    // Only check grid activity every (grid_expiry/10) ms, because it's really useless to do it every cycle
    info.UpdateTimeTracker(t_diff);
    if( info.getTimeTracker().Passed() )
    {
        if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().PlayersNearGrid(x, y, m.GetId(), m.GetInstanceId()) )
        {
            ObjectGridStoper stoper(grid);
            stoper.StopN();
            grid.SetGridState(GRID_STATE_IDLE);
        }
        else
        {
            m.ResetGridExpiry(grid, 0.1f);
        }
    }
}
Пример #7
0
void Basis::setup(const GridInfo& gInfo, const IonInfo& iInfo, double Ecut, const vector3<> k)
{	//Find the indices within Ecut:
	vector3<int> iGbox; for(int i=0; i<3; i++) iGbox[i] = 1 + int(sqrt(2*Ecut) * gInfo.R.column(i).length() / (2*M_PI));
	std::vector< vector3<int> > iGvec;
	std::vector<int> indexVec;
	vector3<int> iG;
	for(iG[0]=-iGbox[0]; iG[0]<=iGbox[0]; iG[0]++)
		for(iG[1]=-iGbox[1]; iG[1]<=iGbox[1]; iG[1]++)
			for(iG[2]=-iGbox[2]; iG[2]<=iGbox[2]; iG[2]++)
				if(0.5*dot(iG+k, gInfo.GGT*(iG+k)) <= Ecut)
				{	iGvec.push_back(iG);
					indexVec.push_back(gInfo.fullGindex(iG));
				}
	setup(gInfo, iInfo, indexVec, iGvec);
	logPrintf("nbasis = %lu for k = ", nbasis); k.print(globalLog, " %6.3f ");
}
Пример #8
0
//################ Droplet on attractive wall ####################
int main(int argc, char** argv)
{	initSystem(argc, argv);

	GridInfo gInfo;
	gInfo.S = vector3<int>(64, 64, 64); double hGrid=1.0;
	//gInfo.S = vector3<int>(128, 128, 128); double hGrid=0.5;
	gInfo.R = Diag(gInfo.S * hGrid);
	gInfo.initialize();

	double T = 298*Kelvin;
	FluidComponent component(FluidComponent::H2O, T, FluidComponent::ScalarEOS);
	component.s2quadType = QuadOctahedron;
	component.Nnorm = 270;
	
	PreconditionedFluidMixture fluidMixture(gInfo, T, 1.0);
	component.addToFluidMixture(&fluidMixture);
	double p = 1.01325*Bar;
	logPrintf("pV = %le\n", p*gInfo.detR);
	fluidMixture.initialize(p);

	#define geomName "AttractiveWall-3bohr-3.0kT/drop_plane"

	bool loadState=false;
	const char stateFilename[] = "TestFixedN/" geomName "_state.bin";

	//Initialize potential: planar wall with attractive well:
	nullToZero(component.idealGas->V, gInfo);
	double xWall = 0.5*gInfo.R(0,0)-21.0;
	double dxWall = 2.0;
	applyFunc_r(gInfo, initAttractiveWall, xWall, dxWall, 100*T, 3.*T, component.idealGas->V[0]->data());

	if(loadState)
		fluidMixture.loadState(stateFilename);
	else
	{	//Initialize state biased towards center of cell
		const double muSet=-5.0;
		const double Rdroplet = 22.0; //guess droplet size:
		nullToZero(fluidMixture.state, gInfo, fluidMixture.get_nIndep());
		applyFunc_r(gInfo, initSphere, gInfo.R*vector3<>(0.5,0.5,0.5), Rdroplet, 0.0, muSet, fluidMixture.state[0]->data());

		RealKernel gauss(gInfo); initGaussianKernel(gauss, 2.0);
		fluidMixture.state[0] = I(gauss*J(fluidMixture.state[0]));

		ScalarField wallMask(ScalarFieldData::alloc(gInfo));
		applyFunc_r(gInfo, initAttractiveWall, xWall, 2*dxWall, 0.0, 1.0, wallMask->data());
		fluidMixture.state[0] *= (wallMask+1.0);
	}

	MinimizeParams mp;
	mp.fpLog = globalLog;
	mp.nDim = 2*gInfo.nr;
	mp.nIterations=10;
	mp.knormThreshold=1e-11;
	mp.dirUpdateScheme = MinimizeParams::FletcherReeves;
	//mp.dirUpdateScheme = MinimizeParams::SteepestDescent;
	//mp.updateTestStepSize = false;
	mp.fdTest = !loadState;

	int sysRet=system("mkdir -p TestFixedN/" geomName "_img");
	if(sysRet) { logPrintf("Error making image directory\n"); mpiUtil->exit(sysRet); }

	for(int loopCount=0; loopCount<100; loopCount++)
	{
		ScalarFieldArray N;
		TIME("getOmega calculation (with gradient)", globalLog,
			double omega = fluidMixture.getFreeEnergy(FluidMixture::Outputs(&N));
			if(std::isnan(omega)) break; //Don't save state after it has become nan
		);
		logPrintf("Ntot = %lf\n", gInfo.dV*sum(N[0]));

		logPrintf("Saving state:\n");
		fluidMixture.saveState(stateFilename);
		saveDX(N[0], "TestFixedN/" geomName "_nO");
		saveDX(N[1], "TestFixedN/" geomName "_nH");
		saveSphericalized(&N[0], 2, "TestFixedN/" geomName "_n.spherical", 0.25);
		//Invoke octave to create an image:
		FILE* pp = popen("octave -q", "w");
		fprintf(pp, "imwrite( waterSlice(\"TestFixedN/" geomName "_n%%s.bin\", [%d %d %d], 1, %d, 1e-2),", gInfo.S[0], gInfo.S[1], gInfo.S[2], gInfo.S[2]/2);
		fprintf(pp, " \"TestFixedN/" geomName "_img/img%04d.png\"); exit;\n", loopCount);
		fflush(pp); pclose(pp);

		logPrintf("Starting CG:\n");
		TIME("minimize", globalLog,
			fluidMixture.minimize(mp);
		);
Пример #9
0
void read(std::vector<ColumnBundle>& Y, const char *fname, const ElecInfo& eInfo, const ColumnBundleReadConversion* conversion)
{	if(conversion && conversion->realSpace)
	{	if(eInfo.qStop==eInfo.qStart) return; //no k-point on this process
		const GridInfo* gInfoWfns = Y[eInfo.qStart].basis->gInfo;
		//Create a custom gInfo if necessary:
		GridInfo gInfoCustom;
		gInfoCustom.R = gInfoWfns->R;
		gInfoCustom.S = conversion->S_old;
		for(int k=0; k<3; k++) if(!gInfoCustom.S[k]) gInfoCustom.S[k] = gInfoWfns->S[k];
		bool needCustom = !(gInfoCustom.S == gInfoWfns->S);
		if(needCustom) { logSuspend(); gInfoCustom.initialize(); logResume(); }
		const GridInfo& gInfo = needCustom ? gInfoCustom : *gInfoWfns;
		//Read one column at a time:
		complexScalarField Icol; nullToZero(Icol, gInfo);
		for(int q=eInfo.qStart; q<eInfo.qStop; q++)
		{	int nCols = Y[q].nCols();
			int nSpinor = Y[q].spinorLength();
			if(conversion->nBandsOld) nCols = std::min(nCols, conversion->nBandsOld);
			for(int b=0; b<nCols; b++) for(int s=0; s<nSpinor; s++)
			{	char fname_qb[1024]; sprintf(fname_qb, fname, q, b*nSpinor+s);
				loadRawBinary(Icol, fname_qb);
				if(needCustom) Y[q].setColumn(b,s, changeGrid(J(Icol), *gInfoWfns));
				else Y[q].setColumn(b,s, J(Icol));
			}
		}
	}
	else
	{	//Check if a conversion is actually needed:
		std::vector<ColumnBundle> Ytmp(eInfo.qStop);
		std::vector<Basis> basisTmp(eInfo.qStop);
		std::vector<long> nBytes(mpiUtil->nProcesses(), 0); //total bytes to be read on each process
		for(int q=eInfo.qStart; q<eInfo.qStop; q++)
		{	bool needTmp = false, customBasis = false;
			int nCols = Y[q].nCols();
			if(conversion)
			{	if(conversion->nBandsOld && conversion->nBandsOld!=nCols)
				{	nCols = conversion->nBandsOld;
					needTmp = true;
				}
				double EcutOld = conversion->EcutOld ? conversion->EcutOld : conversion->Ecut;
				customBasis = (EcutOld!=conversion->Ecut);
				if(customBasis)
				{	needTmp = true;
					logSuspend();
					basisTmp[q].setup(*(Y[q].basis->gInfo), *(Y[q].basis->iInfo), EcutOld, Y[q].qnum->k);
					logResume();
				}
			}
			const Basis* basis = customBasis ? &basisTmp[q] : Y[q].basis;
			int nSpinor = Y[q].spinorLength();
			if(needTmp) Ytmp[q].init(nCols, basis->nbasis*nSpinor, basis, Y[q].qnum);
			nBytes[mpiUtil->iProcess()] += nCols * basis->nbasis*nSpinor * sizeof(complex);
		}
		//Sync nBytes:
		if(mpiUtil->nProcesses()>1)
			for(int iSrc=0; iSrc<mpiUtil->nProcesses(); iSrc++)
				mpiUtil->bcast(nBytes[iSrc], iSrc);
		//Compute offset of current process, and expected file length:
		long offset=0, fsize=0;
		for(int iSrc=0; iSrc<mpiUtil->nProcesses(); iSrc++)
		{	if(iSrc<mpiUtil->iProcess()) offset += nBytes[iSrc];
			fsize += nBytes[iSrc];
		}
		//Read data into Ytmp or Y as appropriate, and convert if necessary:
		MPIUtil::File fp; mpiUtil->fopenRead(fp, fname, fsize, "Hint: Did you specify the correct nBandsOld, EcutOld and kdepOld?\n");
		mpiUtil->fseek(fp, offset, SEEK_SET);
		for(int q=eInfo.qStart; q<eInfo.qStop; q++)
		{	ColumnBundle& Ycur = Ytmp[q] ? Ytmp[q] : Y[q];
			mpiUtil->fread(Ycur.data(), sizeof(complex), Ycur.nData(), fp);
			if(Ytmp[q]) //apply conversions:
			{	if(Ytmp[q].basis!=Y[q].basis)
				{	int nSpinor = Y[q].spinorLength();
					for(int b=0; b<std::min(Y[q].nCols(), Ytmp[q].nCols()); b++)
						for(int s=0; s<nSpinor; s++)
							Y[q].setColumn(b,s, Ytmp[q].getColumn(b,s)); //convert using the full G-space as an intermediate
				}
				else
				{	if(Ytmp[q].nCols()<Y[q].nCols()) Y[q].setSub(0, Ytmp[q]);
					else Y[q] = Ytmp[q].getSub(0, Y[q].nCols());
				}
				Ytmp[q].free();
			}
		}
		mpiUtil->fclose(fp);
	}
}
Пример #10
0
int main(int argc, char** argv)
{	initSystem(argc, argv);

	//Parse command-line
	S2quadType quadType = QuadEuler;
	int nBeta = 12;
	if(argc > 1)
	{	if(!S2quadTypeMap.getEnum(argv[1], quadType))
			die("<quad> must be one of %s\n", S2quadTypeMap.optionList().c_str());
		if(quadType==QuadEuler)
		{	if(argc < 3) die("<nBeta> must be specified for Euler quadratures.\n")
			nBeta = atoi(argv[2]);
			if(nBeta <= 0) die("<nBeta> must be non-negative.")
		}
	}
	
	//Setup simulation grid:
	GridInfo gInfo;
	gInfo.S = vector3<int>(1, 1, 4096);
	const double hGrid = 0.0625;
	gInfo.R = Diag(hGrid * gInfo.S);
	gInfo.initialize();

	double T = 298*Kelvin;
	FluidComponent component(FluidComponent::H2O, T, FluidComponent::ScalarEOS);
	component.s2quadType = quadType;
	component.quad_nBeta = nBeta;
	component.representation = FluidComponent::Pomega;
	FluidMixture fluidMixture(gInfo, T);
	component.addToFluidMixture(&fluidMixture);
	double p = 1.01325*Bar;
	logPrintf("pV = %le\n", p*gInfo.detR);
	fluidMixture.initialize(p);

	//Initialize external potential (repel O from a cube)
	double Dfield = 1.0 * eV/Angstrom;
	const double zWall = 8.0 - 1e-3;
	const double& gridLength = gInfo.R(2,2);
	ScalarField phiApplied(ScalarFieldData::alloc(gInfo)), phiWall(ScalarFieldData::alloc(gInfo));
	applyFunc_r(gInfo, setPhi, phiApplied->data(), phiWall->data(), gridLength, Dfield, zWall);
	const double ZO = component.molecule.sites[0]->chargeKernel(0);
	component.idealGas->V[0] = ZO * phiApplied + phiWall;
	component.idealGas->V[1] = -0.5*ZO * phiApplied + phiWall;

	//----- Initialize state -----
	fluidMixture.initState(0.01);

	//----- FDtest and CG -----
	MinimizeParams mp;
	mp.fpLog = globalLog;
	mp.nDim = gInfo.nr * fluidMixture.get_nIndep();
	mp.energyLabel = "Phi";
	mp.nIterations=1500;
	mp.energyDiffThreshold=1e-16;
	
	fluidMixture.minimize(mp);
	
	//------ Outputs ---------
	ostringstream quadName;
	quadName << S2quadTypeMap.getString(quadType);
	if(quadType == QuadEuler) quadName << nBeta;
	
	ScalarFieldArray N;
	fluidMixture.getFreeEnergy(FluidMixture::Outputs(&N));
	FILE* fp = fopen((quadName.str()+".Nplanar").c_str(), "w");
	double* NOdata = N[0]->data();
	double* NHdata = N[1]->data();
	double nlInv = 1./component.idealGas->get_Nbulk();
	for(int i=0; i<gInfo.S[2]/2; i++)
		fprintf(fp, "%le\t%le\t%le\n", i*hGrid, nlInv*NOdata[i], 0.5*nlInv*NHdata[i]);
	fclose(fp);
	
	finalizeSystem();
	return 0;
}