//... solveEigenstates() .................................................... public void SolveEigenstates() { // allocate the solution vectors x = new double[numberOfStates][]; p = new double[numberOfStates][]; for (var i = 0; i < numberOfStates; i++) { x[i] = new double[dimension]; p[i] = new double[dimension]; } eigenValue = new double[numberOfStates]; // reduce the number of eigenvalues to the maximum possible number var counter = 0; for (row = 0; row < dimension; row++) { if (status[row]) { counter++; } } if (numberOfStates > dimension - counter) { numberOfStates = dimension - counter; } var profileSolverStatus = new ProfileSolverStatus(a, w, y, status, profile); // loop over the specified number of eigenstates for (state = 0; state < numberOfStates; state++) { raleigh = 0; s = 0; // set start vector w0 for (row = 0; row < dimension; row++) { if (status[row]) { w[row] = 0; } else { w[row] = 1; } } // start iteration for next eigenstate double m; do { // increment iteration counter s++; // check if number of iterations is greater Smax if (s > SMax) { throw new AlgebraicException("Eigensolver: too many iterations " + s); } // B-orthogonalization of w(s-1) with respect to all smaller // eigenvectors x[0] to x[state-1] for (var i = 0; i < state; i++) { var c = 0.0; // compute c(i) and subtract c(i)*p(i) from w for (row = 0; row < dimension; row++) { if (!status[row]) { c += w[row] * x[i][row]; } } for (row = 0; row < dimension; row++) { if (!status[row]) { w[row] -= c * p[i][row]; } } } // solve A * y(s) = w(s-1) for y(s) profileSolverStatus.SetRhs(w); profileSolverStatus.SolvePrimal(); // compute z(s) = B * y(s) z = MatrixAlgebra.Mult(b, y, status, profile); // compute m2 = 1 / (y[s] * z[s]) double sum = 0; for (row = 0; row < dimension; row++) { if (!status[row]) { sum += y[row] * z[row]; } } m2 = 1 / sum; // compute Rayleigh quotient r = m2 * y(s)(T) * w(s-1) // and the difference ( r(s) - r(s-1) ) sum = 0; for (row = 0; row < dimension; row++) { if (!status[row]) { sum += y[row] * w[row]; } } sum *= m2; deltaRaleigh = sum - raleigh; raleigh = sum; // compute w(s) = m(s) * z(s) m = Math.Sqrt(Math.Abs(m2)); for (row = 0; row < dimension; row++) { if (!status[row]) { w[row] = m * z[row]; } } // continue iteration as long as change in Rayleigh factor (r(s)-r(s-1) // is greater than error bound } while (Math.Abs(deltaRaleigh) > Math.Abs(RaleighFactor * raleigh)); // store computed eigenstate and vector p=w=Bx for B-orthogonalization eigenValue[state] = raleigh; for (row = 0; row < dimension; row++) { x[state][row] = m * y[row]; p[state][row] = w[row]; } } }
public void Perform() { var alfaDt = alfa * dt; var dtAlfa = dt * (1 - alfa); var primal = new double[dimension]; var timeSteps = Temperature.Length; That = new double[dimension]; Tdot = new double[timeSteps][]; for (var i = 0; i < timeSteps; i++) { Tdot[i] = new double[dimension]; } // calculate initial temperature gradients var rhs = MatrixAlgebra.Mult(k, Temperature[0], profile); for (var i = 0; i < dimension; i++) { Tdot[0][i] = (ForcingFunction[0][i] - rhs[i]) / c[i]; } // evaluate constant coefficient matrix var cm = new double[dimension][]; for (var row = 0; row < dimension; row++) { cm[row] = new double[row + 1 - profile[row]]; for (var col = 0; col <= (row - profile[row]); col++) { cm[row][col] = alfaDt * k[row][col]; } cm[row][row - profile[row]] += c[row]; } var profileSolverStatus = new ProfileSolverStatus(cm, rhs, primal, status, profile); profileSolverStatus.Decompose(); for (var counter = 1; counter < timeSteps; counter++) { // calculate temperature gradients at restrained nodes for (var i = 0; i < dimension; i++) { if (status[i]) { Tdot[counter][i] = (Temperature[counter][i] - Temperature[counter - 1][i]) / dt; } } // calculate T(hat) for next step for (var i = 0; i < dimension; i++) { if (status[i]) { That[i] = Temperature[counter][i]; } else { That[i] = Temperature[counter - 1][i] + dtAlfa * Tdot[counter - 1][i]; } } // modification of RHS rhs = MatrixAlgebra.Mult(k, That, status, profile); var rhSfr = MatrixAlgebra.MultUl(cm, Tdot[counter], status, profile); for (var i = 0; i < dimension; i++) { rhs[i] = ForcingFunction[counter][i] - rhSfr[i] - rhs[i]; } // backsubstitution profileSolverStatus.SetRhs(rhs); profileSolverStatus.SolvePrimal(); // temperatures and gradients at next time step for unrestrained nodes for (var i = 0; i < dimension; i++) { if (status[i]) { continue; } Tdot[counter][i] = primal[i]; Temperature[counter][i] = That[i] + alfaDt * primal[i]; } } }
public void Perform() { double alfa, beta, gamma, theta; if (method == 1) { alfa = 0; theta = 1; beta = parameter1; gamma = parameter2; } else if (method == 2) { beta = 1.0 / 6; gamma = 0.5; alfa = 0; theta = parameter1; } else if (method == 3) { theta = 1; alfa = parameter1; gamma = 0.5 - alfa; beta = 0.25 * (1 - alfa) * (1 - alfa); } else { throw new AlgebraicException("TimeIntegration2NdOrderStatus: invalid method identifier entered"); } var gammaDt = gamma * dt; var betaDt2 = beta * dt * dt; var gammaDtTheta = gamma * dt * theta; var dt1MGamma = dt * (1 - gamma); var dt2MBetaDt2 = dt * dt / 2 - beta * dt * dt; var thetaDt = theta * dt; var thetaDt1MGamma = theta * dt * (1 - gamma); var theta2Dt2MBetaDt2 = theta * theta * dt2MBetaDt2; var betaDt2Theta2AlfaP1 = beta * dt * dt * theta * theta * (1 + alfa); var primal = new double[dimension]; var dual = new double[dimension]; var timeSteps = displacement.Length; acceleration = new double[timeSteps][]; for (var i = 0; i < timeSteps; i++) { acceleration[i] = new double[dimension]; } // calculate initial accelerations at unrestrained dof, for M[i]>0 var rhs = MatrixAlgebra.Mult(k, displacement[0], status, profile); for (var i = 0; i < dimension; i++) { // if (status[i]) continue; ODER wenn M[i]=0 continue --> RHS[i]=0 if (status[i] | m[i] == 0) { continue; } rhs[i] = (forcingFunction[0][i] - c[i] * velocity[0][i] - rhs[i]) / m[i]; acceleration[0][i] = rhs[i]; } // constant coefficient matrix var cm = new double[dimension][]; for (var row = 0; row < dimension; row++) { cm[row] = new double[row + 1 - profile[row]]; for (var col = 0; col <= (row - profile[row]); col++) { cm[row][col] = betaDt2Theta2AlfaP1 * k[row][col]; } cm[row][row - profile[row]] += m[row] + gammaDtTheta * c[row]; } var profileSolverStatus = new ProfileSolverStatus (cm, rhs, primal, dual, status, profile); profileSolverStatus.Decompose(); for (var counter = 1; counter < timeSteps; counter++) { // calculate displacement(hat) and velocity(hat) at n+1 for (var i = 0; i < dimension; i++) { displacement[counter][i] = displacement[counter - 1][i] + thetaDt * velocity[0][i] + theta2Dt2MBetaDt2 * acceleration[counter - 1][i]; velocity[1][i] = velocity[0][i] + thetaDt1MGamma * acceleration[counter - 1][i]; } // calculate new RHS for (var i = 0; i < dimension; i++) { rhs[i] = (1 + alfa) * displacement[counter][i] - alfa * displacement[counter - 1][i]; } rhs = MatrixAlgebra.Mult(k, rhs, status, profile); for (var i = 0; i < dimension; i++) { if (!status[i]) { rhs[i] = (1 - theta) * forcingFunction[counter - 1][i] + theta * forcingFunction[counter][i] - c[i] * velocity[1][i] - rhs[i]; } } // backsubstitution profileSolverStatus.SetRhs(rhs); profileSolverStatus.SolvePrimal(); // displacements, velocities and accelerations at next time step for (var i = 0; i < dimension; i++) { if (status[i]) { continue; } acceleration[counter][i] = acceleration[counter - 1][i] + (primal[i] - acceleration[counter - 1][i]) / theta; displacement[counter][i] = displacement[counter - 1][i] + dt * velocity[0][i] + dt2MBetaDt2 * acceleration[counter - 1][i] + betaDt2 * acceleration[counter][i]; velocity[0][i] = velocity[0][i] + dt1MGamma * acceleration[counter - 1][i] + gammaDt * acceleration[counter][i]; } } }