Пример #1
0
        // Eigensolutions ***********************************************************************************************************
        public void Eigenstates()
        {
            var numberOfStates = modell.Eigenstate.NumberOfStates;
            var aMatrix        = systemEquations.Matrix;

            if (!diagonalMatrix)
            {
                ComputeDiagonalMatrix();
            }
            var bDiag = systemEquations.DiagonalMatrix;

            // general B-Matrix is expanded to the same structure as A
            var bMatrix = new double[dimension][];
            int row;

            for (row = 0; row < aMatrix.Length; row++)
            {
                bMatrix[row] = new double[aMatrix[row].Length];
                int col;
                for (col = 0; col < bMatrix[row].Length - 1; col++)
                {
                    bMatrix[row][col] = 0;
                }
                bMatrix[row][col] = bDiag[row];
            }

            if (!decomposed)
            {
                profileSolver = new ProfileSolverStatus(
                    systemEquations.Matrix,
                    systemEquations.Status, systemEquations.Profile);
                profileSolver.Decompose();
                decomposed = true;
            }

            var eigenSolver = new Eigensolver(systemEquations.Matrix, bMatrix,
                                              systemEquations.Profile, systemEquations.Status,
                                              numberOfStates);

            eigenSolver.SolveEigenstates();

            // save eigenvalues and eigenvectors
            var eigenvalues  = new double[numberOfStates];
            var eigenvectors = new double[numberOfStates][];

            for (var i = 0; i < numberOfStates; i++)
            {
                eigenvalues[i]  = eigenSolver.GetEigenValue(i);
                eigenvectors[i] = eigenSolver.GetEigenVector(i);
            }
            modell.Eigenstate.Eigenvalues  = eigenvalues;
            modell.Eigenstate.Eigenvectors = eigenvectors;
            modell.Eigenstate.Status       = systemEquations.Status;
            modell.Eigen = true;
        }
Пример #2
0
        public void SolveEquations()
        {
            if (!decomposed)
            {
                profileSolver = new ProfileSolverStatus(
                    systemEquations.Matrix, systemEquations.Vector,
                    systemEquations.Primal, systemEquations.Dual,
                    systemEquations.Status, systemEquations.Profile);
                profileSolver.Decompose();
                decomposed = true;
            }
            profileSolver.Solve();
            // ... save system unknowns (primal values)
            foreach (var item in modell.Knoten)
            {
                node = item.Value;
                var index = node.SystemIndices;
                node.NodalDof = new double[node.NumberOfNodalDof];
                for (var i = 0; i < node.NodalDof.Length; i++)
                {
                    node.NodalDof[i] = systemEquations.Primal[index[i]];
                }
            }
            // ... save dual values
            var reactions = systemEquations.Dual;

            foreach (var support in modell.Randbedingungen.Select(item => item.Value))
            {
                node = support.Node;
                var index           = node.SystemIndices;
                var supportReaction = new double[node.NumberOfNodalDof];
                for (var i = 0; i < supportReaction.Length; i++)
                {
                    supportReaction[i] = reactions[index[i]];
                }
                node.Reactions = supportReaction;
            }
            modell.Solved = true;
        }
Пример #3
0
        //... 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];
                }
            }
        }