internal double[] calculateDyDt(double[] vols, double[] forcing) { //System.Array.Clear(dydt,0,lengthOfStateVector); double[] tempDyDt = new double[lengthOfStateVector]; for (int i = 0; i < vols.Length; i++) //MB: Constraining to volumes above or equal to zero. { if (vols[i] < 0) { vols[i] = 0; } } foreach (Connection con in connections) { try { int j = con.from; double x = con.calculateFlow(vols); tempDyDt[j] -= x; if (con.to != System.Int32.MaxValue) //outlets are given MaxValue as magic number. { tempDyDt[con.to] += x; } } catch (Exception ex1) { Exception ex2 = new Exception("Time t=: " + t + " Error calculating flow: " + nodes[con.from].name + " to " + nodes[con.to].name + " vol in from node=" + vols[con.from], ex1); throw ex2; } } tempDyDt = RungeKutta4.arrSum(tempDyDt, forcing); return(tempDyDt); }
internal double[] calculateDyDt(double[] vols, double[] forcing) { //System.Array.Clear(dydt,0,lengthOfStateVector); double[] tempDyDt = new double[lengthOfStateVector]; for (int i = 0; i < vols.Length; i++) //MB: Constraining to volumes above or equal to zero. { if (vols[i] < 0) { vols[i] = 0; } } for (int i = 0; i < qSplits.Length; i++) { qSplits[i] = 0; qMassSplits[i] = 0; } foreach (Connection con in connections) { try { if (!con.bFromFlowDivider) { double q = con.calculateFlow(vols); tempDyDt[con.from] -= q; double qMass = 0; if (bIncludeWQ) { if (vols[con.from] < virtuallyZero) { qMass = 0; } else { qMass = q * vols[con.from + NhydraulicStates] / vols[con.from]; //mass flux calculated as flow times mass / volume; } tempDyDt[con.from + NhydraulicStates] -= qMass; } if (con.bToFlowDivider) { this.qSplits[con.to] += q; //add flow to the right flow divider. if (bIncludeWQ) { this.qMassSplits[con.to] += qMass; } } else { if (con.to != System.Int32.MaxValue) //outlets are given MaxValue as magic number. { tempDyDt[con.to] += q; if (bIncludeWQ) { tempDyDt[con.to + NhydraulicStates] += qMass; } } } if (con.bIsOutput) { con.accumFlow(q); //for calculating output flow as avereage of all solver steps. if (bIncludeWQ) { con.accumMassFlux(qMass); } } } } catch (Exception ex1) { Exception ex2 = new Exception("Time t=: " + t + " Error calculating flow: " + nodes[con.from].name + " to " + nodes[con.to].name + " vol in from node=" + vols[con.from], ex1); throw ex2; } } foreach (FlowDivider fd in flowDividers) { //if (bIncludeWQ) throw new NotImplementedException("WQ not implemented for flow dividers yet"); int Ncons = fd.connections.Count; double[] qs = new double[Ncons]; int[] stateVectorIndexes = new int[Ncons]; int i = 0; foreach (FlowDividerConnection con in fd.connections) { //calculate flow from all flow dividers. The flow to has been calculated above. qs[i] = con.calculateFlow(qSplits); if (con.to != System.Int32.MaxValue) //outlets are given MaxValue as magic number. { tempDyDt[con.to] += qs[i]; stateVectorIndexes[i] = con.to; } if (con.bIsOutput) { con.accumFlow(qs[i]); //for calculating output flow as avereage of all solver steps. } i++; } if (bIncludeWQ) { double sumx = qs.Sum();//total flow from divider. double qMassInTotal = qMassSplits[fd.index] + fd.qMassFixed; for (int j = 0; j < Ncons; j++) { double qMassx; if (sumx < virtuallyZero) { qMassx = 0; } else { qMassx = qMassInTotal * qs[j] / sumx; } tempDyDt[stateVectorIndexes[j] + NhydraulicStates] += qMassx; if (fd.connections[j].bIsOutput) { fd.connections[j].accumMassFlux(qMassx); } } } } tempDyDt = RungeKutta4.arrSum(tempDyDt, forcing); return(tempDyDt); }