public double InitializeAndGetResidual(IList <ISolverSubdomain> subdomains, double[] r, double[] x)
        {
            double detf = 0;
            double temp = 0;

            if (subdomains.Count != 1)
            {
                throw new InvalidOperationException("Cannot initialize and calculate residuals with more than one subdomains");
            }

            foreach (ISolverSubdomain subdomain in subdomains)
            {
                Array.Copy(((Vector <double>)subdomain.RHS).Data, r, subdomain.RHS.Length);
                //subdomain.SubdomainToGlobalVector(((Vector<double>)subdomain.RHS).Data, r);
                var s = (SkylineMatrix2D <double>)subdomain.Matrix;

                if (preconditioner == null)
                {
                    preconditioner = (SkylineMatrix2D <double>)s.Clone();
                    preconditioner.Factorize(1e-8, new List <Vector <double> >(), new List <int>());
                }
            }

            for (int i = 0; i < r.Length; i++)
            {
                temp  = r[i];
                detf += temp * temp;
            }
            return(Math.Sqrt(detf));
        }
Esempio n. 2
0
        private void MakeKiiDictionary()
        {
            foreach (var subdomain in subdomainsDictionary)
            {
                SubdomainSkyline         s = (SubdomainSkyline)subdomain.Value;
                SkylineMatrix2D <double> k = (SkylineMatrix2D <double>)s.Matrix;
                //var internalDOFs = model.Subdomains[s.ID].NodalDOFsDictionary.SelectMany(x => x.Value.Values).Except(boundaryDOFsDictionary[s.ID]).OrderBy(x => x).ToArray<int>();
                var   internalDOFs = internalDOFsDictionary[s.ID];
                int[] kiiIx        = new int[internalDOFs.Count + 1];
                int   curIx        = 0;
                for (int i = 0; i < internalDOFs.Count; i++)
                {
                    kiiIx[i] = curIx;
                    int row     = internalDOFs[i];
                    int fromCol = row - k.RowIndex[row + 1] + k.RowIndex[row] + 1;
                    var newCols = internalDOFs.Count(x => x >= fromCol && x <= row);
                    curIx += newCols;
                }
                kiiIx[internalDOFs.Count] = curIx;

                SkylineMatrix2D <double> kii = new SkylineMatrix2D <double>(kiiIx);
                curIx = 0;
                for (int i = 0; i < internalDOFs.Count; i++)
                {
                    int row     = internalDOFs[i];
                    int fromCol = row - k.RowIndex[row + 1] + k.RowIndex[row] + 1;
                    var newCols = internalDOFs.Where(x => x >= fromCol && x <= row).OrderByDescending(x => x).ToArray <int>();
                    for (int j = 0; j < newCols.Length; j++)
                    {
                        kii.Data[curIx] = k.Data[k.RowIndex[row] + row - newCols[j]];
                        curIx++;
                    }
                }

                kii.Factorize(1e-8, new List <Vector <double> >(), new List <int>());
                kiiDictionary.Add(s.ID, kii);
            }
        }
        private void MakePreconditioner(int simulation)
        {
            int    matrixNo = matrixOrder[simulation + blockSize / 2];
            string name     = String.IsNullOrWhiteSpace(stiffnessMatrixPath) ? "K" : stiffnessMatrixPath;
            string path     = Path.GetDirectoryName(name);
            string nameOnly = Path.GetFileNameWithoutExtension(name);
            string ext      = Path.GetExtension(name);

            foreach (var sub in subdomains)
            {
                var m = new SkylineMatrix2D <double>(new int[0]);
                m.ReadFromFile(String.Format("{0}\\{1}Sub{3}Sim{4}{2}", path, nameOnly, ext, sub.Key, matrixNo));
                m.Factorize(1e-8, new List <Vector <double> >(), new List <int>());
                if (factorizedMatrices.ContainsKey(sub.Key))
                {
                    factorizedMatrices[sub.Key] = m;
                }
                else
                {
                    factorizedMatrices.Add(sub.Key, m);
                }
            }
        }