@@ -54,24 +54,33 @@ void FC cgWthrClean( // cgwthr overall init/cleanup routine
5454 cgWfDone (); // close any open weather file
5555
5656// init weather file info record
57- Wfile.wf_Init (); // mbr function in wfpak.cpp sets record to say no file open
58- Wthr.wd_Init (); // mbr function in wfpak.cpp clears record
59- WthrNxHr.wd_Init (); // mbr function in wfpak.cpp clears record
57+ Wfile.wf_Init (); // sets record to say no file open
58+ Wthr.wd_Init (); // clears record
59+ WthrNxHr.wd_Init (); // clears record
6060
6161 // add any other init/cleanup found necessary or desirable
6262
6363} // cgWthrClean
6464// ---------------------------------------------------------------------------
65- RC TOPRAT::tp_WfInit () // Initialize weather file. Displays any error messages.
66- // also uses: Top. tp_wfName [,.isDT]
65+ RC TOPRAT::tp_WthrInit () // Initialize weather data/ display any error messages.
66+ // also uses: tp_wfName, tp_TDVfName, [,.isDT]
6767// returns non-RCOK if error, message already issued.
6868{
6969 RC rc = Wfile.wf_Open ( tp_wfName, tp_TDVfName); // open wthr file and option TDV file
7070 // init WFILE object, msg if error.
7171 if (!rc)
72- rc = Wfile.wf_FillWDYEAR ( WRN);
72+ rc = Wfile.wf_FillWDYEAR ( WRN); // read/cache entire weather file
73+ // TODO: handle partial years
74+
75+ // design conditions
76+ // set any derived values
77+ // WHY here: location dependence, call after locinit
78+ DESCOND* pDC;
79+ RLUP ( DcR, pDC)
80+ rc |= pDC->dc_RunInit ();
81+
7382 return rc;
74- } // TOPRAT::tp_WfInit
83+ } // TOPRAT::tp_WthrInit
7584// ---------------------------------------------------------------------------
7685RC TOPRAT::tp_WthrBegHour () // start-hour weather stuff: read file, set up public Wthr and Top members.
7786// tp_WthrBegSubhr must also be called, after this function.
@@ -432,7 +441,7 @@ RC WDHR::wd_WfReader( // read an hour's weather data and make adjustments
432441 if (Top.tp_AuszWthrSource () == TOPRAT_COOLDSCOND)
433442 { // DSCOND design day: overwrite/adjust weather file values with generated
434443 int iDC = Top.tp_coolDsCond [ Top.tp_dsDayI -1 ];
435- const DESCOND& DC = DCiB [ iDC];
444+ const DESCOND& DC = DcR [ iDC];
436445 wd_FillFromDESCOND ( DC, iHrST);
437446 }
438447 }
@@ -517,7 +526,7 @@ RC WDHR::wd_WfReader( // read an hour's weather data and make adjustments
517526 rc = pWF->wf_Read( jDayST, iHrST, this, WRN|wfOp); // Read hour's data from weather file
518527 if (Top.tp_AuszWthrSource() == TOPRAT_COOLDSCOND)
519528 { int iDC = Top.tp_coolDsCond[ Top.tp_dsDayI-1];
520- const DESCOND& DC = DCiB [ iDC];
529+ const DESCOND& DC = DcR [ iDC];
521530 DC.dc_GenerateTemps( iHrST, this);
522531
523532 }
@@ -611,11 +620,12 @@ void WDHR::wd_FillFromDESCOND( // overwrite/adjust hourly data for design condi
611620 wd_taDbAvg14 += dbAvgDiff / 14 .f ;
612621 wd_taDbAvg31 += dbAvgDiff / 31 .f ;
613622
614-
615623 wd_wndSpd = dc.dc_wndSpd ;
616624 wd_wndDir = 0 .f ;
617625
618- if (wd_sunup)
626+ // derive irradiance
627+ // note: tauB/tauD both 0 -> no solar
628+ if (wd_sunup && dc.dc_tauB > 0 .f && dc.dc_tauD > 0 .f )
619629 wd_glrad = slASHRAETauModel (
620630 kPiOver2 - wd_slAlt,
621631 dc.dc_tauB , dc.dc_tauD ,
@@ -636,17 +646,107 @@ void WDHR::wd_FillFromDESCOND( // overwrite/adjust hourly data for design condi
636646// ///////////////////////////////////////////////////////////////////////////
637647RC DESCOND::dc_CkF () // check after input
638648{ RC rc = RCOK;
639- if (dc_MCWB > dc_DB)
640- rc |= oer ( " dcMCWB (%g) must be <= dcDB (%g)" , dc_MCWB, dc_DB);
641649 return rc;
642650} // DESCOND::dc_CkF
643651// -----------------------------------------------------------------------------
644- DOY DESCOND::dc_GetDOY () const
652+ #if defined( _DEBUG)
653+ static void DCTauTest ( int doy)
645654{
646- return dc_day;
655+ float ebnlist[] = { 150 .f , 200 .f , 250 .f , 300 .f , -1 .f };
656+ float edflist[] = { 20 .f , 30 .f , 40 .f };
657+
658+ DESCOND dc ( &DcR, 1 );
659+ dc.dc_doy = doy;
660+ strcpy ( dc.name , " Test" );
661+
662+ for (int ib=0 ; ebnlist[ ib]>=0 .f ; ib++)
663+ { dc.dc_ebnSlrNoon = ebnlist[ ib];
664+ for (int id=0 ; edflist[ id]>=0 .f ; id++)
665+ { dc.dc_edhSlrNoon = edflist[ id];
666+ dc.dc_CheckFixSolar ( 0 );
667+ }
668+ }
669+ } // DCTauTest
670+ #endif
671+ // ------------------------------------------------------------------------------
672+ RC DESCOND::dc_RunInit () // init for run
673+ // call after all input-time expressions have been evaluated
674+ // call after locInit (re latitude dependency)
675+ {
676+ #if defined( _DEBUG)
677+ static int tested = 0 ;
678+ if (!tested)
679+ { DCTauTest ( dc_doy);
680+ tested++;
681+ }
682+ #endif
647683
648- } // DESCOND::dc_GetDOY
684+ RC rc = RCOK;
685+
686+ if (dc_MCWB > dc_DB)
687+ rc |= oer ( " dcMCWB (%g) must be <= dcDB (%g)" , dc_MCWB, dc_DB);
649688
689+ // if any solar values given, check and cross-derive
690+ // else leave all 0 = no solar
691+ if (dc_tauB + dc_tauD + dc_ebnSlrNoon + dc_edhSlrNoon > 0 .f )
692+ { int nTau = IsSetCount ( DESCOND_TAUB, DESCOND_TAUD, 0 );
693+ int nE = IsSetCount ( DESCOND_EBNSLRNOON, DESCOND_EDHSLRNOON, 0 );
694+ if (nTau == 0 )
695+ rc |= dc_CheckFixSolar ( 0 ); // derive tauB / tauD
696+ else if (nE == 0 )
697+ rc |= dc_CheckFixSolar ( 1 ); // derive Ebn / Edh
698+ else
699+ rc |= oer ( " must give either dcTauB/dcTauD and"
700+ " not dcEbnSlrNoon/dcEdhSlrNoon or vice-versa" );
701+ }
702+ else
703+ oInfo ( " no irradiance due to dcTauB/dcTauD/dcEbnSlrNoon/dcEdhSlrNoon all 0" );
704+
705+ return rc;
706+ } // DESCOND::dc_RunInit
707+ // -----------------------------------------------------------------------------
708+ RC DESCOND::dc_CheckFixSolar (
709+ int options) // option bits
710+ // 0: derive tau from solar noon
711+ // 1: derive solar noon from tau
712+ {
713+ RC rc = RCOK;
714+
715+ // solar noon angles
716+ slday ( dc_doy, SLTMSOLAR, 1 );
717+ float sunAlt, sunAzm;
718+ slaltazm ( 12 .f , &sunAlt, &sunAzm);
719+ float sunZen = kPiOver2 - sunAlt;
720+
721+ if (options & 1 )
722+ { rc |= limitCheck ( DESCOND_TAUB, .08 , 1 .)
723+ | limitCheck ( DESCOND_TAUD, 1.2 , 3.2 );
724+ if (!rc)
725+ slASHRAETauModel ( sunZen, dc_tauB, dc_tauD,
726+ dc_ebnSlrNoon, dc_edhSlrNoon);
727+ }
728+ else
729+ { rc |= limitCheck ( DESCOND_EBNSLRNOON, 0 ., 370 .)
730+ | limitCheck ( DESCOND_EDHSLRNOON, 0 ., 110 .);
731+ if (!rc)
732+ { bool ret = slASHRAETauModelInv ( sunZen, dc_ebnSlrNoon, dc_edhSlrNoon,
733+ dc_tauB, dc_tauD);
734+ if (!ret)
735+ rc = oer ( " failed to derive dcTauB and dcTauD."
736+ " Check dcEbnSlrNoon and dcEdhSlrNoon input values." );
737+ #if defined( _DEBUG)
738+ else
739+ { float ebn, edh;
740+ float egl = slASHRAETauModel ( sunZen, dc_tauB, dc_tauD, ebn, edh);
741+ if (frDiff ( ebn, dc_ebnSlrNoon) > .01f
742+ || frDiff ( edh, dc_edhSlrNoon) > .01f )
743+ oWarn ( " ebn/edh mismatch" );
744+ }
745+ #endif
746+ }
747+ }
748+ return rc;
749+ } // DESCOND::dc_CheckFixSolar
650750// -----------------------------------------------------------------------------
651751void DESCOND::dc_GenerateTemps (
652752 int iHr, // hour of day (0 - 23)
0 commit comments