// Update vsh inside the statcom converter public void update(AclfNetwork net) throws InterpssException { Complex vi = net.getAclfBus(id).getVoltage(); Complex vsh1 = this.converter.getVth(); if (type == StatcomControlType.ConstB) { // Control of constant shunt admittance Complex vsh = solveConstB(vsh1, vi, this.converter, tunedValue); this.converter.setVth(vsh); } else if (type == StatcomControlType.ConstQ) { // Control of constant shunt reactive power compensation Complex vsh = solveConstQ(vsh1, vi, this.converter, tunedValue); this.converter.setVth(vsh); } else if (type == StatcomControlType.ConstV) { // Control of constant voltage magnitude Complex vsh = solveConstV(vsh1, vi, this.converter, tunedValue); this.converter.setVth(vsh); } Complex vsh2 = this.converter.getVth(); if (type != StatcomControlType.ConstV) err = (vsh1.subtract(vsh2)).abs(); }
// Calculate Vsh to match the tuned constant Q private Complex solveConstQ(Complex vsh1, Complex vi, ConverterLF converter, double tunedValue) { double qerr = 100.0; Complex vsh = vsh1; double vmsh = vsh.abs(); double thetash = Math.atan2(vsh.getImaginary(), vsh.getReal()); double vmi = vi.abs(); double thetai = Math.atan2(vi.getImaginary(), vi.getReal()); double gsh = converter.getYth().getReal(); double bsh = converter.getYth().getImaginary(); // Iteration by Newton method while (qerr > 0.0001) { // Active power balance equation Fp: active output of v source = 0 double fp = vmsh * vmsh * gsh - vmi * vmsh * (gsh * Math.cos(thetai - thetash) - bsh * Math.sin(thetai - thetash)); // Reactive power balance equation Fq: reactive injection at bus i = -Qsh ("-" means injecting // other than absorbing) double fq = -tunedValue + vmi * vmi * bsh + vmi * vmsh * (gsh * Math.sin(thetai - thetash) - bsh * Math.cos(thetai - thetash)); // Update the mismatch qerr = Math.max(Math.abs(fp), Math.abs(fq)); // Jacobian double a = 2 * vmsh * gsh - vmi * (gsh * Math.cos(thetai - thetash) - bsh * Math.sin(thetai - thetash)); // dFp/dVsh double b = -vmi * vmsh * (gsh * Math.sin(thetai - thetash) + bsh * Math.cos(thetai - thetash)); // dFp/dThetash double c = vmi * (gsh * Math.sin(thetai - thetash) - bsh * Math.cos(thetai - thetash)); // dFq/dVsh double d = -vmi * vmsh * (gsh * Math.cos(thetai - thetash) + bsh * Math.sin(thetai - thetash)); // dFq/dThetash // Solve the mismatch equation double det = a * d - b * c; double dvmsh = (d * fp - b * fq) / det; double dthetash = (-c * fp + a * fq) / det; // Update Vsh and thetash vmsh -= dvmsh; thetash -= dthetash; } System.out.println("thetai=" + thetai + ", thetash=" + thetash); return new Complex(vmsh * Math.cos(thetash), vmsh * Math.sin(thetash)); }
// Calculate Vsh to match the tuned constant B private Complex solveConstB(Complex vsh1, Complex vi, ConverterLF converter, double tunedValue) { double berr = 100.0; Complex vsh = vsh1; double vmsh = vsh.abs(); double thetash = Math.atan2(vsh.getImaginary(), vsh.getReal()); double vmi = vi.abs(); double thetai = Math.atan2(vi.getImaginary(), vi.getReal()); double gsh = converter.getYth().getReal(); double bsh = converter.getYth().getImaginary(); // Iteration by Newton method while (berr > 0.00001) { // Active power balance equation Fp: active output of v source = 0 double fp = vmsh * vmsh * gsh - vmi * vmsh * (gsh * Math.cos(thetai - thetash) - bsh * Math.sin(thetai - thetash)); // Shunt admittance equation Fb: shunt admittance at bus i = Vi / Ishunt double fb = vmsh * (gsh * Math.sin(thetash - thetai) + bsh * Math.cos(thetash - thetai)) + vmi * (tunedValue - bsh); // Update the mismatch berr = Math.max(Math.abs(fp), Math.abs(fb)); // Jacobian double a = 2 * vmsh * gsh - vmi * (gsh * Math.cos(thetai - thetash) - bsh * Math.sin(thetai - thetash)); // dFp/dVsh double b = -vmi * vmsh * (gsh * Math.sin(thetai - thetash) + bsh * Math.cos(thetai - thetash)); // dFp/dThetash double c = gsh * Math.sin(thetash - thetai) + bsh * Math.cos(thetash - thetai); // dFb/dVsh double d = vmsh * (gsh * Math.cos(thetash - thetai) - bsh * Math.sin(thetash - thetai)); // dFb/dThetash // Solve the mismatch equation double det = a * d - b * c; double dvmsh = (d * fp - b * fb) / det; double dthetash = (-c * fp + a * fb) / det; // Update Vsh and thetash vmsh -= dvmsh; thetash -= dthetash; } return new Complex(vmsh * Math.cos(thetash), vmsh * Math.sin(thetash)); }
/** * This operation returns the value of the squared modulus of the specular reflectivity for a * single wave vector Q. * * @param waveVectorQ the value of the wave vector * @param wavelength the wavelength of the incident neutrons * @param tiles the list of Tiles that contains the physical parameters needed for the * calculation, including the scattering densities, absorption parameters and thicknesses. * @return the squared modulus of the specular reflectivity */ public double getModSqrdSpecRef(double waveVectorQ, double wavelength, Tile[] tiles) { double modSqrdSpecRef = 0.0; if (wavelength > 0.0) { // Variables only needed if we are going to do the work, i.e. - // wavelength > 0.0. Tile tile; Complex aNm1Sq, fNm1N, rNm1N = new Complex(0.0, 0.0), one = new Complex(1.0, 0.0), qN = new Complex(0.0, 0.0), rNNp1 = new Complex(0.0, 0.0); // Get the bottom tile int nLayers = tiles.length; tile = tiles[nLayers - 1]; // Starting point--no reflected beam in bottom-most (bulk) layer double qCSq = 16.0 * Math.PI * tile.scatteringLength; double muLAbs = tile.trueAbsLength; double mulInc = tile.incAbsLength; double thickness = tile.thickness; // Setup other values for the problem double betaNm1 = 4.0 * Math.PI * (muLAbs + mulInc / wavelength); Complex qNm1 = new Complex(waveVectorQ * waveVectorQ - qCSq, -2.0 * betaNm1); qNm1 = qNm1.sqrt(); // Loop through to calculate recursion formula described in Parratt. // Start at the bottom and work up. for (int i = nLayers - 1; i > 0; i--) { // Get the tile above tile[i] (started at the bottom tile = tiles[i - 1]; // Calculate the normal component of Q for layer and layer-1 qN = qNm1; qCSq = 16.0 * Math.PI * tile.scatteringLength; muLAbs = tile.trueAbsLength; mulInc = tile.incAbsLength; thickness = tile.thickness; betaNm1 = 4.0 * Math.PI * (muLAbs + mulInc / wavelength); qNm1 = new Complex(waveVectorQ * waveVectorQ - qCSq, -2.0 * betaNm1); qNm1 = qNm1.sqrt(); // Calculate phase factor, e^(-0.5*d*qNm1) aNm1Sq = (new Complex(qNm1.getImaginary(), qNm1.getReal()).multiply(-0.5 * thickness)).exp(); // CDiv(qNm1-qN,qNm1+qN) fNm1N = qNm1.subtract(qN).divide(qNm1.add(qN)); // Calculate the reflectivity amplitude. // CMult(aNm1Sq, CMult(aNm1Sq, CDiv(CAdd(rNNp1, fNm1N), // CAdd(CMult(rNNp1, fNm1N), CReal(1))))) Complex y = rNNp1.multiply(fNm1N).add(one); Complex z = rNNp1.add(fNm1N); rNm1N = aNm1Sq.multiply(aNm1Sq).multiply(z.divide((y))); // Carry over to the next iteration rNNp1 = rNm1N; } modSqrdSpecRef = rNm1N.getReal() * rNm1N.getReal() + rNm1N.getImaginary() * rNm1N.getImaginary(); } return modSqrdSpecRef; }