/* This file is part of Cloudy and is copyright (C) 1978-2004 by Gary J. Ferland.
 * For conditions of distribution and use, see copyright notice in license.txt */
/*AgeCheck check various timescales after calculation complete to confirm time steady OK */
#include "cddefines.h"
#include "physconst.h"
#include "timesc.h"
#include "prt.h"
#include "hmi.h"
#include "co.h"
#include "struc.h"
#include "warnings.h"
#include "dense.h"
#include "agecheck.h"

void AgeCheck(void)
{
	char chLine[INPUT_LINE_LENGTH];
	long int i, 
	  limit;
	double hold,
	  tlong, 
	  tsound;

#	ifdef DEBUG_FUN
	fputs( "<+>AgeCheck()\n", debug_fp );
#	endif

	/* cloud age of zero means that age command turned off
	 * negative cloud age means was not set */

	/* remember longest timescale */
	tlong = 0.;

	/* thermal equilibrium timescale */
	timesc.ttherm = 0.;
	limit = MAX2(1,nzone-1);
	ASSERT( limit < struc.nzlim );

	/* NZLIM is the size of the struc vectors - should be dynamic 
	limit = MIN2( limit , NZLIM-1 );*/

	for( i=0; i < limit; i++ )
	{
		timesc.ttherm = 
			MAX2( timesc.ttherm ,
			struc.DenParticles[i]*BOLTZMANN*1.5*struc.testr[i]/struc.coolstr[i]);
		/*>>chng 99 feb 01, had div by heating, changed to cooling so constant
		 * temperature models are more realistic */
	}

	tlong = MAX2(tlong,timesc.ttherm);
	if( prt.lgPrnAges )
	{
		sprintf( chLine, "   AGE: longest thermal timescale= %.2es.", 
		  timesc.ttherm );
		notein(chLine);
	}

	tlong = MAX2(tlong,timesc.TimeH21cm);
	if( prt.lgPrnAges )
	{
		sprintf( chLine, "   AGE: 21 cm equilibrium timescale= %.2es.", 
		  timesc.TimeH21cm );
		notein(chLine);
	}

	if( timesc.CloudAgeSet > 0. && timesc.ttherm > timesc.CloudAgeSet )
	{
		sprintf( chLine, " C-AGE: Thermal equilibrium timescale, %.2es, longer than age", 
		  timesc.ttherm );
		caunin(chLine);
	}

	/* check soundt travel time if constant pressure */
	if( strcmp(dense.chDenseLaw,"CPRE") == 0 )
	{
		tsound = timesc.sound;
		if( prt.lgPrnAges )
		{
			sprintf( chLine, "   AGE: sound travel time= %.2es.", 
			  tsound );
			notein(chLine);
		}

		if( timesc.CloudAgeSet > 0. && tsound > timesc.CloudAgeSet )
		{
			sprintf( chLine, " C-AGE: Sound travel time longer than age in constant pressure model = %.2es", 
			  timesc.ttherm );
			caunin(chLine);
		}
	}

	else
	{
		/* do not check if not constant pressure */
		tsound = 0.;
	}
	tlong = MAX2(tlong,tsound);

	/* molecule formation timescale */
	/* >>chng 04 sep 17, - if species are negligible will set to negative number
	 * to retain value but not include in timescales */
	if( hmi.BiggestH2<1e-2 )
	{
		timesc.time_H2_Dest_longest *= -1.;
		timesc.time_H2_Form_longest *= -1.;
	}
	if( co.xMoleFracMax[ipCO] < 1e-2 )
	{
		timesc.BigCOMoleForm *= -1.;
	}
	tlong = MAX2( tlong , timesc.time_H2_Dest_longest );
	tlong = MAX2( tlong , timesc.time_H2_Form_longest );
	tlong = MAX2( tlong , timesc.BigCOMoleForm );

	/* >>chng 97 jan 03, don't print if zero */
	if( prt.lgPrnAges && timesc.time_H2_Dest_longest > 0. )
	{
		sprintf( chLine, "   AGE: longest H2 destruction timescale= %.2es.", 
		  timesc.time_H2_Dest_longest );
		notein(chLine);
	}

	if( prt.lgPrnAges && timesc.time_H2_Form_longest > 0. )
	{
		sprintf( chLine, "   AGE: longest H2 formation timescale= %.2es.", 
		  timesc.time_H2_Form_longest );
		notein(chLine);
	}

	if( timesc.CloudAgeSet > 0. && timesc.time_H2_Dest_longest > timesc.CloudAgeSet )
	{
		sprintf( chLine, " C-AGE: H2 destruction timescale longer than age, = %.2es", 
		  timesc.time_H2_Dest_longest );
		caunin(chLine);
	}

	if( timesc.CloudAgeSet > 0. && timesc.time_H2_Form_longest > timesc.CloudAgeSet )
	{
		sprintf( chLine, " C-AGE: H2 formation timescale longer than age, = %.2es", 
		  timesc.time_H2_Form_longest );
		caunin(chLine);
	}

	if( prt.lgPrnAges && timesc.BigCOMoleForm > 0. )
	{
		sprintf( chLine, "   AGE: longest CO formation timescale= %.2es.", 
		  timesc.BigCOMoleForm );
		notein(chLine);
	}

	if( timesc.CloudAgeSet > 0. && timesc.BigCOMoleForm > timesc.CloudAgeSet )
	{
		sprintf( chLine, " C-AGE: CO formation timescale longer than age, = %.2es", 
		  timesc.BigCOMoleForm );
		caunin(chLine);
	}

	/* hydrogen recombination timescale */
	timesc.threc = 0.;
	for( i=0; i < limit; i++ )
	{
		hold = struc.ednstr[i]*2.90e-10*pow(struc.testr[i],-0.77f);
		timesc.threc = MAX2(timesc.threc , 1./hold);
	}

	tlong = MAX2(tlong,timesc.threc);
	if( prt.lgPrnAges )
	{
		sprintf( chLine, "   AGE: longest H recombination timescale= %.2es.", 
		  timesc.threc );
		notein(chLine);
	}

	if( timesc.CloudAgeSet > 0. && timesc.threc > timesc.CloudAgeSet )
	{
		sprintf( chLine, " C-AGE: Hydrogen recombination timescale longer than age, = %.2es", 
		  timesc.threc );
		caunin(chLine);
	}

	/* give age in various units, depending on order of magnitude */
	if( timesc.CloudAgeSet < 0. )
	{
		/* CloudAgeSet initially set to -1, if still the case then age not set */
		if( tlong < 3600. )
		{
			/* less than one day, give only seconds */
			sprintf( chLine, "  !AGE: Cloud age was not set.  Longest timescale was %.2e s.", 
			  tlong );
			bangin(chLine);
		}

		else if( tlong < 8.64e4 )
		{
			/* less than one day, give seconds and hours */
			sprintf( chLine, "  !AGE: Cloud age was not set.  Longest timescale was %.2e s = %.2e hours.", 
			  tlong, tlong/3600. );
			bangin(chLine);
		}

		else if( tlong < 3e7/12. )
		{
			/* less than one month, give seconds and days */
			sprintf( chLine, "  !AGE: Cloud age was not set.  Longest timescale was %.2e s = %.2e days.", 
			  tlong, tlong/86400. );
			bangin(chLine);
		}

		else if( tlong < 3e7 )
		{
			/* less than one year, give seconds and months */
			sprintf( chLine, "  !AGE: Cloud age was not set.  Longest timescale was %.2e s = %.2e months.", 
			  tlong, (tlong/3.15569e7)*12. );
			bangin(chLine);
		}

		else
		{
			/* more than one year, give seconds and years */
			sprintf( chLine, "  !AGE: Cloud age was not set.  Longest timescale was %.2e s = %.2e years.", 
			  tlong, tlong/3.15569e7 );
			bangin(chLine);
		}
	}

	else
	{
		/* age set, and passed tests, still say longest */
		if( tlong < 3e7 )
		{
			/* less than one year, give only seconds */
			sprintf( chLine, "   AGE: Cloud age was %.2es, Longest timescale was %.2e s.", 
			  timesc.CloudAgeSet, tlong );
			notein(chLine);
		}

		else
		{
			/* more than one year, give seconds and years */
			sprintf( chLine, "   AGE: Cloud age was %.2e s.  Longest timescale was %.2e s = %.2e years.", 
			  timesc.CloudAgeSet, tlong, tlong/3.15569e7 );
			notein(chLine);
		}
	}

#	ifdef DEBUG_FUN
	fputs( " <->AgeCheck()\n", debug_fp );
#	endif
	return;
}

