#pragma rtGlobals=3 // Use modern global access method and strict wave access. // Modified by Ken Aikin from code that Steve Brown had for doing 1-D chemical model of plume. // Modified code now does dispersion in X and Y with chemistry. // To run, choose Macros->Run_Model2() // Prompts for number of downwind rows, and cross-wind columns, as well as timestep for each iteration, and the dispersion fraction. // This dispersion fraction is used to disperse the plume by colvolving that wave with the concentrations for each species. // Dispersion is calculated with the wave {dispersion fraction, 1-2*(dispersion fraction), dispersion fraction} i.e. {0.05, 0.9, 0.05} // The sum of that wave should always be 1 to conserve mass. // KA 20151102 // Mods: // Clean up indentation, and replace many spaces with tabs in DispersionMechanismCompile(). Delete empty "else" statements. // Add function removeDuplicatesInTextWave() to cleanup Names wave with possible duplicates. // Remove unused variables in RunDispersionModel() // T and Prs // KA 20160510 // Add columns to table after running Mechanism_Setup. // Need to change Macro RateConst() to be run sometime (when T and/or Prs change) and change macro to function. // Add new wave BackgroundConc to table. Use this instead of having to add variables to code for passing in values. // Add the menu items to "Macros" menu for running Chem/Dispersion model. // KA 20160511 // Fix bugs in DispersionMechanismCompile() that caused out of bounds error for Names wave while looking for matching string in reactants and products waves. // Put in break statements as more graceful way to exit loops. // KA 20160512 Menu "Macros" "---" "Dispersion Mechanism_Setup" "Dispersion Mechanism Compile" "Run Dispersion Model" "DoManyModelRuns" "transect" "---" end // Macro to call RunDispersionModel() repeatedly for doing lots of runs. Store runs in data folders using SaveModelRun() in Results.ipf // Specific case for varying N2O5_LossRate,MonoBkg,AlkBkg,AldBkg,Dispersion,NO_emissions,O3_background in model runs. // Make it more general later? macro DoManyModelRuns() variable refNum, n, num string runName Print "Select a comma-delimited file containing model run parameters" NewDataFolder/O/S root:MultipleRuns Loadwave/J/A/W/O // prompt for comma-delimited file of parameters for model runs. num = numpnts(N2O5_LossRate) SetDataFolder root: do // set up parameters loaded from comma-delimited file above BackgroundConc[5] = root:MultipleRuns:MonoBkg[n] // CHANGE THESE to row number of background value BackgroundConc[10] = root:MultipleRuns:AlkBkg[n] // CHANGE THESE BackgroundConc[12] = root:MultipleRuns:AldBkg[n] // CHANGE THESE BackgroundConc[1] = root:MultipleRuns:O3_background[n] // CHANGE THESE RateCoefficients[5] = root:MultipleRuns:N2O5_LossRate[n]*(1-root:MultipleRuns:ClNO2_) RateCoefficients[6] = root:MultipleRuns:N2O5_LossRate[n]*(root:MultipleRuns:ClNO2_) runName = "run_"+num2str(root:MultipleRuns:N2O5_loss[n])+"_"+num2str(root:MultipleRuns:Mon[n])+"_"+num2str(root:MultipleRuns:Disp[n])+"_"+num2str(root:MultipleRuns:NO_emissions[n])+"_"+num2str(root:MultipleRuns:O3_background[n]) //sprintf runName, "run_%03d", n // do simple miethod for now. Make n+last# if running multiple times in one experiment PRINT runName // debug DispersionMechanismCompile("ChemKinetic") RunDispersionModel(14, root:MultipleRuns:Dispersion[n], 60, root:MultipleRuns:NO_emissions[n], .1) // RunDispersionModel(TotalTime, DiffPerSec, TimeStep, NOconc, NOwidth) // make sure these are right for the defaults ExtractSpeciesFromLayer("All") transect(720) Display NOy_transect append NO_transect, NO2_transect, NO3_transect, N2O5_transect, HNO3_transect, ClNO2_transect, MonNO3_transect, AlkNO3_transect, Pan_transect, orgN_transect Make/O/N=17 Areas InitializeAlmostEverything("NO_transect","_calculated_","_none_") InitAreaBetweenCursors1(3,"NO_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[0] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"NO2_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[2] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"NO3_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[3] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"N2O5_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[4] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"HNO3_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[8] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"ClNO2_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[9] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"MonNO3_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[6] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"AlkNO3_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[11] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"Pan_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[14] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"orgN_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[15] = W_AreaNoBase[0] InitAreaBetweenCursors1(3,"NOy_transect","_calculated_","_None_",1) AreaBetweenCursors1() Areas[16] = W_AreaNoBase[0] SaveModelRun(runName) n+=1 while(n1) Abort "Error in DiffFraction" endif // Z is in order of Names wave Make/D/O/N=(NumRows, NumCols, NumSpecies) resultsMatrix=0 // concentrations. Row=downwind distance. Column=crosswind dist. Layer=species. Make/D/O/N=(NumCols) DownWindSlice // Make/D/O/N=3 sm_coefs={0.05, 0.9, 0.05} // wave that gets convolved with concentration to do downwind dispersion. Default Make/D/O/N=3 sm_coefs={DiffFraction, 1-2*DiffFraction, DiffFraction} // wave that gets convolved with concentration to do downwind dispersion. Larger middle number is less dispersion. Wave needs to add up to 1. CalTime[1] = TimeStep for(n=1; n0) if (TotalLen>390) // string too long for one line in function breakpos = StrSearch(Totaltemp, "+", 300) // find first "+" past 300 chars if (breakpos<0 || breakpos> 390) breakpos = StrSearch(Totaltemp, "-", 300)) // Check if there's maybe a "-" endif if (breakpos>300) //Print "dydt["+ num2str(n) + "]=" + Totaltemp[0,breakpos-1] //Print "dydt["+ num2str(n) + "]+=" + Totaltemp[breakpos, StrLen(Totaltemp)-1] dydtstr += "dydt["+ num2str(n) + "]="+Totaltemp[0,breakpos-1] + "\r" dydtstr += "dydt["+ num2str(n) + "]+="+ Totaltemp[breakpos, StrLen(Totaltemp)-1] + "\r" else //print Totaltemp abort "something is strange with this string" endif else //Print "dydt["+ num2str(n) + "]=" + Totaltemp dydtstr += "dydt["+ num2str(n) + "]=" + Totaltemp+ "\r" endif endif n +=1 while (n < SpeciesNumber) RemoveChemKineticFuncs() Execute/Q /P "EditChemKineticFuncs()" IncludeChemKineticFuncs() end // Keep for now to refer to original setup for model without dispersion. //Macro Run_Model2_ORIG() // ORIGINAL CODE // // Silent 1 // // If (!exists("CurrChemKineticFct")) // Abort "Must compile ODE first!" // Endif // String cmd, SpeciesList, CurrSpecies // Variable n, speciesnumber // Variable npnts // SetDataFolder root: // Silent 1 // PauseUpdate // Variable starttime = DateTime // n=0 // SpeciesList = "" // SpeciesNumber = numpnts(Names) // Do // if(n == 0) // SpeciesList += Names[n] // else // SpeciesList = SpeciesList + "," + Names[n] // endif // n += 1 // while (n < numpnts(Names)) // // n=0 // Do // CurrSpecies = Names[n] // print $CurrSpecies // // $CurrSpecies[0] = InitialConcentrations[n] // restart: initialize to original values // n += 1 // while(n < SpeciesNumber) // // cmd= "IntegrateODE/U=1000/X=CalTime "+CurrChemKineticFct+" KK, {"+ SpeciesList + "}" // //Print cmd // Execute cmd // //print "Calculation time", DateTime - starttime,"seconds" // //end Macro Transect(p3) variable p3 make/N=201/D/O NO_transect, NO2_transect, O3_transect, NO3_transect, N2O5_transect, HNO3_transect, ClNO2_transect, MonNO3_transect, AlkNO3_transect, PAN_transect, Ace_transect, NOy_transect, OrgN_transect SetScale/I x -10,10,"", NO_transect, NO2_transect, O3_transect, NO3_transect, N2O5_transect, HNO3_transect, ClNO2_transect, MonNO3_transect, AlkNO3_transect, PAN_transect, Ace_transect, NOy_transect, OrgN_transect NO_transect = NO_mat[p3][p] NO2_transect = NO2_mat[p3][p] O3_transect = O3_mat[p3][p] HNO3_Transect = HNO3_mat[p3][p] N2O5_Transect = N2O5_mat[p3][p] NO3_Transect = NO3_mat[p3][p] ClNO2_Transect = ClNO2_mat[p3][p] MonNO3_transect = MonNO3_mat[p3][p] AlkNO3_transect = AlkNO3_mat[p3][p] PAN_transect = PAN_mat[p3][p] Ace_transect = Ace_mat[p3][p] NOy_transect = NO_transect + NO2_transect + HNO3_transect + 2*N2O5_transect + NO3_transect + ClNO2_transect + MonNO3_transect + AlkNO3_transect + PAN_transect OrgN_transect = MonNO3_transect + AlkNO3_transect //print p3 End Macro function removeDuplicatesInTextWave(textwaveStr) string textwaveStr variable n, len, start string species wave/T tw = $textwaveStr len = numpnts(tw) for (n=0; n=0; n-=1) if (cmpstr(twave[n], "")!=0) foundIt = 1 break endif endfor if (foundIt) return n else return -1 endif end