private Hashtable<Spezies, Double> calc_dmj_dp() { Hashtable<Spezies, Double> massenBruchHash_Zone = gg_Zone.get_speziesMassenBruecheDetail(); Hashtable<Spezies, Double> dmj_dp = new Hashtable<Spezies, Double>(); Enumeration<Spezies> e = massenBruchHash_Zone.keys(); Spezies spez; if (loeseChemGleichgwicht == true && burns == true) { double delta_p = 5000; GasGemisch rauchgas = new GasGemisch( GG_SOLVER.get_GG_molenBrueche(p_Zone + delta_p, T_Zone, gg_Zone), "rauchgas_temp_" + ID); Hashtable<Spezies, Double> rgSpezMassenBrueche = rauchgas.get_speziesMassenBruecheDetail(); while (e.hasMoreElements()) { spez = e.nextElement(); dmj_dp.put( spez, (m_Zone * (rgSpezMassenBrueche.get(spez) - massenBruchHash_Zone.get(spez))) / delta_p); } } else { while (e.hasMoreElements()) { spez = e.nextElement(); dmj_dp.put(spez, 0.0); } } return dmj_dp; }
/** * Mit dieser Methode kann ein Massenelement eines Gases mit der Temperatur T_m der Zone mit der * Temperatur T_Zone zugemischt werden. Die sich ergebende Mischungstemperatur wird für * VERÄNDERLICHE CVs und ein adiabates System nach dem ersten HS berechnet. Das Volumen der Zone * bleibt Konstant --> das zugemischte Massenelement leistet Verschiebearbeit! * * @param m_Zu --> zugemischtes Massenelement [kg] * @param T_Zu --> Temperatur des zugemischten Massenelements [K] * @param s_Zu --> Zusammensetzung des Massenelements */ public void massenElementZumischenKonstVol(double m_Zu, double T_Zu, Spezies s_Zu) { // adiabate Mischungstemperatur nach dem ersten Hauptsatz double Tm = 278.15, U1, U_zu, U1m, U_zum, Cvm1, Cv_zum, F, dF, Tm_buffer; U1 = gg_Zone.get_u_mass(T_Zone) * m_Zone; U_zu = s_Zu.get_u_mass(T_Zu) * m_Zu; int idx = 0; // Newtonverfahren für F(Tm)= U1(T1)+U2(T2)-U1(Tm)-U2(Tm)=0 // mit dF/dT=-m1*Cv1(Tm)-m2*Cv2(Tm) do { Tm_buffer = Tm; U1m = gg_Zone.get_u_mass(Tm) * m_Zone; U_zum = s_Zu.get_u_mass(Tm) * m_Zu; Cvm1 = gg_Zone.get_cv_mass(Tm) * m_Zone; Cv_zum = s_Zu.get_cv_mass(Tm) * m_Zu; F = U1 + U_zu - U1m - U_zum; dF = -Cvm1 - Cv_zum; Tm = Tm - F / dF; idx++; } while (idx < 1000 && Math.abs(Tm - Tm_buffer) > 0.1); if (idx >= 1000) { try { throw new MiscException("t"); } catch (MiscException me) { me.log_Warning("Mangelnde Konvergenz bei der Berechnung der Mischungstemperatur"); } } T_Zone = Tm; // dieser Aufruf muss nach der Temperaturberechnung erfolgen da sich hier die Masse der Zone // ändert massenElementZumischen(m_Zu, s_Zu); }
/** * Mit dieser Methode kann ein Massenelement eines Gases mit der Temperatur T_m der Zone mit der * Temperatur T_Zone zugemischt werden. Die sich ergebende Mischungstemperatur wird für * VERÄNDERLICHE CVs und ein adiabates System nach dem ersten HS berechnet. Das Volumen der Zone * bleibt Konstant --> das zugemischte Massenelement leistet Verschiebearbeit! * * @param m_Zu --> zugemischtes Massenelement [kg] * @param T_Zu --> Temperatur des zugemischten Massenelements [K] * @param s_Zu --> Zusammensetzung des Massenelements */ public void massenElementZumischenKonstVolEinfacher(double m_Zu, double T_Zu, Spezies s_Zu) { // Nach dem 1HS gilt: dm*h=dU double dH = m_Zu * s_Zu.get_h_mass(T_Zu); double U_Zone_mass_temp = m_Zone * gg_Zone.get_u_mass(T_Zone) + dH; // dieser Aufruf muss vor der Temperaturberechnung erfolgen da sich hier die Masse und die // Zusammensetzung // der Zone ändert massenElementZumischen(m_Zu, s_Zu); // Berechnen der Mischungstemperatur U_Zone_mass_temp = U_Zone_mass_temp / m_Zone; T_Zone = gg_Zone.get_T4u_mass(U_Zone_mass_temp); }
private double[] calc_dudT_dRdT() { double[] du_dt_dR_dT = new double[2]; double delta_T = 1; // if-Abfrage nur dann sinnvoll wenn Einfriertemperatur unter 1000K // oder wenn Luft als Rauchgas mit sehr gro§em Lambda modelliert wird if (T_Zone > 1000 && T_Zone <= 1001) { delta_T = -1; } // Berechnen der kalorischen Daten für Rauchgas if (loeseChemGleichgwicht == true && T_Zone >= GG_SOLVER.get_T_Freeze()) { GasGemisch zoneGG = new GasGemisch(GG_SOLVER.get_GG_molenBrueche(p_Zone, T_Zone, gg_Zone), "zoneGG" + ID); GasGemisch rauchgas = new GasGemisch( GG_SOLVER.get_GG_molenBrueche(p_Zone, T_Zone - delta_T, gg_Zone), "rauchgasZone" + ID); // ist zwar umstaendlich aber ich hab schon alles mit Java erlebt :-( double a = (zoneGG.get_u_mass(T_Zone) - rauchgas.get_u_mass(T_Zone - delta_T)); du_dt_dR_dT[0] = a / delta_T; a = (zoneGG.get_R() - rauchgas.get_R()); du_dt_dR_dT[1] = a / delta_T; } else { du_dt_dR_dT[0] = gg_Zone.get_cv_mass(T_Zone); // hier ändert sich die Zusammensetzung des Gases nicht mehr du_dt_dR_dT[1] = 0; } return du_dt_dR_dT; }
/** * Mit dieser Methode kann eine Zone mit einer anderen gemischt werden. Das Volumen der beiden * Zonen wird addiert entsprechent wird keine Verschiebearbeit geleistet. Temperaur, Masse und * Zusammensetzung werden entsprechend {@link massenElementZumischen} berechnet * * @param Zone zone2 --> die Zone die zugemischt werden soll */ public void zoneZumischen(Zone zone2) { double m_Zu = zone2.get_m(); double T_Zu = zone2.get_T(); double V_Zu = zone2.get_V(); Spezies s_Zu = zone2.get_ggZone(); // Nach dem 1HS gilt: -pdV+dm*h=dU --> -p*deltaV+deltaH=deltaU=U2-U1 --> U2=U1+deltaH-p*deltaV double H_zu = m_Zu * s_Zu.get_h_mass(T_Zu); // deltaV=V_zu außerdem ist der Druck in beiden Zonen identisch double U2_Zone_mass = m_Zone * gg_Zone.get_u_mass(T_Zone) + H_zu - p_Zone * V_Zu; // dieser Aufruf muss vor der Temperaturberechnung erfolgen da sich hier die Masse und die // Zusammensetzung // der Zone ändert massenElementZumischen(m_Zu, s_Zu); // Berechnen der Mischungstemperatur T_Zone = gg_Zone.get_T4u_mass(U2_Zone_mass / m_Zone); }
public double[] get_MoleFractions() { Hashtable<Spezies, Double> mf = gg_Zone.get_speziesMolenBruecheDetailToIntegrate(); double x[] = new double[CP.SPEZIES_FABRIK.get_NmbrOfAllSpez()]; Enumeration<Spezies> e = mf.keys(); Spezies spez; while (e.hasMoreElements()) { spez = e.nextElement(); x[CP.SPEZIES_FABRIK.get_indexOf(spez)] = mf.get(spez); } return x; }
public double[] get_mi() { // TODO mach mich mi[] zur Klassenvariablen, dann duerfte es etwas schneller rechnen Hashtable<Spezies, Double> mb = gg_Zone.get_speziesMassenBruecheDetailToIntegrate(); double mi[] = new double[CP.SPEZIES_FABRIK.get_NmbrOfAllSpez()]; Enumeration<Spezies> e = mb.keys(); Spezies spez; while (e.hasMoreElements()) { spez = e.nextElement(); mi[CP.SPEZIES_FABRIK.get_indexOf(spez)] = mb.get(spez) * m_Zone; } return mi; }
private double[] calc_dudp_dRdp() { double[] du_dp_dR_dp = new double[2]; double delta_p = 5000; // Berechnen der kalorischen Daten für Rauchgas if (loeseChemGleichgwicht == true && T_Zone >= GG_SOLVER.get_T_Freeze()) { GasGemisch zoneGG = new GasGemisch(GG_SOLVER.get_GG_molenBrueche(p_Zone, T_Zone, gg_Zone), "zoneGG" + ID); GasGemisch rauchgas = new GasGemisch( GG_SOLVER.get_GG_molenBrueche(p_Zone + delta_p, T_Zone, gg_Zone), "rauchgasZone" + ID); double a = (rauchgas.get_u_mass(T_Zone) - zoneGG.get_u_mass(T_Zone)); du_dp_dR_dp[0] = a / delta_p; a = (rauchgas.get_R() - zoneGG.get_R()); du_dp_dR_dp[1] = a / delta_p; } else { du_dp_dR_dp[0] = 0; du_dp_dR_dp[1] = 0; } return du_dp_dR_dp; }
private Hashtable<Spezies, Double> calc_dmj_dT() { Hashtable<Spezies, Double> massenBruchHash_Zone = gg_Zone.get_speziesMassenBruecheDetail(); Hashtable<Spezies, Double> dmj_dT = new Hashtable<Spezies, Double>(); Enumeration<Spezies> e = massenBruchHash_Zone.keys(); Spezies spez; // Berechnen der kalorischen Daten für Rauchgas if (loeseChemGleichgwicht == true && burns == true) { double delta_T = 1; // if-Abfrage nur dann sinnvoll wenn Einfriertemperatur unter 1000K // oder wenn Luft als Rauchgas mit sehr gro§em Lambda modelliert wird if (T_Zone > 1000 && T_Zone <= 1001) { delta_T = -1; } GasGemisch rauchgas = new GasGemisch( GG_SOLVER.get_GG_molenBrueche(p_Zone, T_Zone - delta_T, gg_Zone), "rauchgas"); Hashtable<Spezies, Double> rgSpezMassenBrueche = rauchgas.get_speziesMassenBruecheDetail(); while (e.hasMoreElements()) { spez = e.nextElement(); dmj_dT.put( spez, (m_Zone * (massenBruchHash_Zone.get(spez) - rgSpezMassenBrueche.get(spez)) / delta_T)); } } else { while (e.hasMoreElements()) { spez = e.nextElement(); dmj_dT.put(spez, 0.0); } } return dmj_dT; }
public static Zone zonenMischen(CasePara cp, Zone z1, Zone z2, boolean burns, int ID) { double p = z1.get_p(); // fuer beide Zonen gleich double m1 = z1.get_m(); double T1 = z1.get_T(); double V1 = z1.get_V(); Spezies s1 = z1.get_ggZone(); double m2 = z2.get_m(); double T2 = z2.get_T(); double V2 = z2.get_V(); Spezies s2 = z2.get_ggZone(); // Erzeugen einer Spezies die durch die Mischung der beiden ZonenSpezies entsteht GasGemisch s0 = new GasGemisch("zonenGemisch"); Hashtable<Spezies, Double> ht0 = new Hashtable<Spezies, Double>(3); double mGes = m1 + m2; ht0.put(s1, m1 / mGes); ht0.put(s2, m2 / mGes); s0.set_Gasmischung_massenBruch(ht0); // Berechnung der Mischungstemperatur // 1.HS --> Kontrollraumgrenze wird um beide Zonen gelegt // Dann gilt: Umisch=U1+U2; double Umisch = m1 * s1.get_u_mass(T1) + m2 * s2.get_u_mass(T2); // Berechnung der Temperatur bei der die innere Energie von Spezies s0=Umisch ist. // Dies entspricht der Mischungstemperatur double T0 = s0.get_T4u_mass(Umisch / mGes); // Das Volumen beider Zonen wird addiert double V0 = V1 + V2; // Test ob alles stimmt double pV = z1.get_p() * V0; double mRT = mGes * T0 * s0.get_R(); double T = (m1 * s1.get_cv_mass(T1) * T1 + m2 * s2.get_cv_mass(T2) * T2) / (m1 * s1.get_cv_mass(T1) + m2 * s2.get_cv_mass(T2)); double deltaT = (T - T0) / T0 * 100; double T3 = pV / mGes / s0.get_R(); double mRT2 = mGes * T * s0.get_R(); double mRT3 = mGes * T3 * s0.get_R(); // Fazit ueber die Gasgleichung geht es auch und zwar viel einfacher und genauer! Zone z0 = new Zone(cp, p, V0, T0, mGes, s0, burns, ID); return z0; }
/** * Mit dieser Methode kann ein Massenelement eines Gases der Zone zugemischt werden. --> es wird * nur die Zusammensetzung und die Gesamtmasse der Zone geändert nicht aber die Temperatur * * @param idx --> Rechenindex * @param mZu --> zugemischtes Massenelement [kg] * @param sZu --> SpeziesObjekt des Massenelements */ public void massenElementZumischen(double mZu, Spezies sZu) { Hashtable<Spezies, Double> massenBruchHash_Zone = gg_Zone.get_speziesMassenBruecheDetail(); Hashtable<Spezies, Double> massenBruchHashNeu = new Hashtable<Spezies, Double>(4); double m_Zone_neu = mZu + m_Zone; if (m_Zone_neu < 0) { try { throw new MiscException( "ERROR: Aus Zone " + ID + " wird mehr Masse entnommen als vorhanden ist"); } catch (MiscException miscE) { miscE.stopBremo(); } } Hashtable<Spezies, Double> einzelMassenHashIn = new Hashtable<Spezies, Double>(); // einzelmassen der zugefuehrten Spezies bestimmen if (mZu < 0) { if (sZu.isGasGemisch()) { einzelMassenHashIn = // enthaelt negative Werte!! this.get_einzelMassenHash(((GasGemisch) sZu).get_speziesMassenBruecheDetail(), mZu); } else { einzelMassenHashIn.put(sZu, mZu); } // einzelmassen der Zone bestimmen Hashtable<Spezies, Double> einzelMassenHashZone = this.get_einzelMassenHash(massenBruchHash_Zone, m_Zone); // Addieren der einzelnen Massen von Zone und sZu Enumeration<Spezies> e = einzelMassenHashZone.keys(); Spezies spez; double mTemp; while (e.hasMoreElements()) { spez = e.nextElement(); mTemp = einzelMassenHashZone.get(spez); if (einzelMassenHashIn.containsKey(spez)) mTemp = mTemp + einzelMassenHashIn.get(spez); // Wert in Hashtable ist negativ double massenBruch = mTemp / m_Zone_neu; massenBruchHashNeu.put(spez, massenBruch); if (massenBruch < 0) { // kommt vor wenn eine Masse entnommen werden soll die gar nicht in der Zone ist! try { throw new MiscException( "ERROR: In einer Zone tritt ein negativer Massenbruch auf \n" + spez.get_name() + ": " + massenBruch); } catch (MiscException miscE) { massenBruchHashNeu.put(spez, 0d); // miscE.stopBremo(); //TODO check mich } } } } else { massenBruchHashNeu.put(gg_Zone, m_Zone / m_Zone_neu); if (massenBruchHashNeu.containsKey( sZu)) { // ==True wenn der Zone eine Masse von sich selbst zugefuehrt wird massenBruchHashNeu.put(gg_Zone, 1D); } else massenBruchHashNeu.put(sZu, mZu / m_Zone_neu); } Hashtable<Spezies, Double> molenBruchHash = new Hashtable<Spezies, Double>(4); molenBruchHash = GasGemisch.Gasmischer.massenBruch2molenBruch(massenBruchHashNeu); GasGemisch gasGemisch = new GasGemisch(molenBruchHash, ""); // würde man hier die gg_Zone.set_Gasmischung_molenBruch(gasGemisch.get_speziesMolenBruecheDetail()); m_Zone = m_Zone_neu; }
public double get_bT() { double bT = -m_Zone * gg_Zone.get_R() - m_Zone * T_Zone * dRdT; return bT; }
/** * Berechnet den Massenverlust bei entnahme einer BESTIMMTEN Spezies Dieser Aufruf sollte nur vom * einzonigen Modell benoetigt werden * * @param dm_a [kg] muss groeser Null sein * @throws NegativeMassException */ public void set_dm_aus(double dm_a, Spezies spez) throws NegativeMassException { if (dm_a < 0) throw new IllegalArgumentException( "\"set_dm_aus()\" wurde fuer Zone " + ID + " mit einem negativen Massenstrom aufgerufen"); if (dm_a > 0) { // Hinzufügen der Einzelmassen der entnommenen Spezies zur Hashtable dmj Hashtable<Spezies, Double> einzelMassenHash_aus = new Hashtable<Spezies, Double>(); if (spez.isGasGemisch() && CP.SPEZIES_FABRIK.isToIntegrate(spez) == false) { Hashtable<Spezies, Double> massenBruchHash_aus = ((GasGemisch) spez).get_speziesMassenBruecheDetailToIntegrate(); // Erstellen der Hashtable mit den Einzelmassen der Grundspezies (CO2, O2, usw.... einzelMassenHash_aus = this.get_einzelMassenHash(massenBruchHash_aus, dm_a); } else { einzelMassenHash_aus.put(spez, dm_a); } // Hinzufügen der Änderung der Grundspeziesmassen Enumeration<Spezies> e = einzelMassenHash_aus.keys(); Spezies spez1; while (e.hasMoreElements()) { spez1 = e.nextElement(); if (!CP.SPEZIES_FABRIK.isToIntegrate(spez1)) { try { throw new BirdBrainedProgrammerException( "Aus Zone " + this.ID + " wurde eine Spezies " + "(" + spez1.get_name() + ") entnommen die nicht integriert werden soll" + " (\"isToIntegrate()\" liefert false)"); } catch (BirdBrainedProgrammerException bbpe) { bbpe.stopBremo(); } } if (!gg_Zone.get_speziesMassenBruecheDetailToIntegrate().containsKey(spez1) && einzelMassenHash_aus.get(spez1) > 0) // Es kann sein, dass Spezies mit einem Massenbruch von 0 in der Hashtable // stehen throw new NegativeMassException( "Aus Zone " + this.ID + " soll eine Spezies" + "(" + spez1.get_name() + ") entnommen werden " + "die in der Zone nicht vorhanden ist"); } e = null; e = einzelMassenHash_aus.keys(); spez1 = null; while (e.hasMoreElements()) { spez1 = e.nextElement(); if (this.dm_aus.containsKey(spez1)) { this.dm_aus.put(spez1, einzelMassenHash_aus.get(spez1) + dm_aus.get(spez1)); } else { this.dm_aus.put(spez1, einzelMassenHash_aus.get(spez1)); } } // e=null; // e=einzelMassenHash_aus.keys(); // spez1=null; // double dmCheck=0; // while(e.hasMoreElements()){ // spez1=e.nextElement(); // dmCheck+=einzelMassenHash_aus.get(spez1); // } // if(dmCheck!=dm_a) // System.out.println("Zone.set_dm_aus: dm_a !=dmCheck " + ((dmCheck-dm_a)) ); // das hier muss nach der NegativeMassException stehen!! Wenn die Exception geworfen // wird und dieser Code ist schon ausgefuehrt wuerde die Energie aber nicht dei Masse // beruecksichtigt double dU = spez.get_u_mass(T_Zone) * dm_a; sumdU = sumdU - dU; double dH = spez.get_h_mass(T_Zone) * dm_a; sumdH = sumdH - dH; } }
public void set_p_V_T_mi( double p_init, double V_init, double T_init, Hashtable<Spezies, Double> mi) { this.p_Zone = p_init; this.V_Zone = V_init; this.T_Zone = T_init; if (p_Zone <= 0 || V_Zone <= 0 || T_Zone <= 0 || (((Double) p_Zone).isNaN()) || (((Double) T_Zone).isNaN()) || (((Double) V_Zone).isNaN())) { try { throw new NegativeMassException( "Falsche Werte in Zone " + this.ID + "\n V= " + V_Zone + "\n p= " + p_Zone + "\n T= " + T_Zone); } catch (NegativeMassException nmE) { nmE.log_Warning(); } } if (CP.get_aktuelle_Rechenzeit() > CP.SYS.WRITE_INTERVAL_SEC) { // System.out.println("xsi: "+this.get_xsi()); // System.out.println("eta: " +this.get_eta()); } if (T_Zone > T_max_Zone) T_max_Zone = T_Zone; // Überprüfen ob die Berechnung der Dissoziation Sinn macht if (T_max_Zone >= GG_SOLVER.get_T_Freeze() && burns) loeseChemGleichgwicht = true; // Berechnen der Gesamtmasse double mGes = 0.0D; double mi_; Enumeration<Spezies> e = mi.keys(); Spezies spez; while (e.hasMoreElements()) { spez = e.nextElement(); mi_ = mi.get(spez); if (mi_ < 0) { if (Math.abs(mi_) >= 0.00001 * CP.SYS.MINIMALE_ZONENMASSE) { try { throw new NegativeMassException( spez.get_name() + " in Zone " + this.ID + " hatte eine negative Masse (" + mi_ + "kg). Die Masse wurde auf null gesetzt!"); } catch (NegativeMassException nmE) { nmE.log_Warning(); } } mi_ = 0; mi.put(spez, mi_); } mGes = mGes + mi_; } spez = null; e = null; this.m_Zone = mGes; if (this.m_Zone > 0) { // Berechnen der Massenbrueche Hashtable<Spezies, Double> massenBrueche = new Hashtable<Spezies, Double>(); e = mi.keys(); double xi; while (e.hasMoreElements()) { spez = e.nextElement(); xi = mi.get(spez) / mGes; massenBrueche.put(spez, xi); } gg_Zone.set_Gasmischung_massenBruch(massenBrueche); // Berechnen der Dissoziation if (loeseChemGleichgwicht == true) gg_Zone.set_Gasmischung_molenBruch(GG_SOLVER.get_GG_molenBrueche(p_Zone, T_Zone, gg_Zone)); } else { Hashtable<Spezies, Double> massenBrueche = new Hashtable<Spezies, Double>(); Spezies co2 = CP.SPEZIES_FABRIK.get_spezCO2(); massenBrueche.put(co2, 1D); // TODO irgendwie uncool gg_Zone.set_Gasmischung_massenBruch(massenBrueche); } double pV = p_Zone * V_Zone; double mRT = m_Zone * gg_Zone.get_R() * T_Zone; // This accounts for inaccuracy during the integration process. // The differences in temperature should be very very small!! // if(CP.get_time()>CP.convert_KW2SEC(5.2)) // System.out.println(); if (pV != mRT && m_Zone > 0 && V_Zone > 0) { // System.out.println("(pV-mRT)/pV: "+(pV-mRT)/pV*100); double T_temp = pV / m_Zone / gg_Zone.get_R(); this.T_Zone = T_temp; double chkPv = pV - m_Zone * gg_Zone.get_R() * T_temp; double chkT = Math.abs((T_Zone - T_temp) / T_temp); if (chkT > 7.555e-3 && m_Zone > CP.SYS.MINIMALE_ZONENMASSE) { try { throw new MiscException( "The temperature of zone " + this.ID + " had to be adjusted too much! " + "chkT= " + chkT); } catch (MiscException me) { me.log_Warning(); } } } dmj_ein = new Hashtable<Spezies, Double>(); dm_aus = new Hashtable<Spezies, Double>(); sumdQ = 0; sumdH = 0; sumdU = 0; dudp = this.calc_dudp_dRdp()[0]; dRdp = this.calc_dudp_dRdp()[1]; dudT = this.calc_dudT_dRdT()[0]; dRdT = this.calc_dudT_dRdT()[1]; }