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)); }
public void BuildMatrices() { if (childAnalyzer == null) { throw new InvalidOperationException("Monte Carlo analyzer must contain an embedded analyzer."); } if (currentSimulation < 0) { InitializeCoefficientsProvider(); } provider.Reset(); coefficientsProvider.CurrentOrder = -1; childAnalyzer.BuildMatrices(); matrices[0] = new Dictionary <int, IMatrix2D <double> >(subdomains.Count); foreach (var subdomain in subdomains.Values) { SkylineMatrix2D <double> k = (SkylineMatrix2D <double>)subdomain.Matrix; matrices[0].Add(subdomain.ID, (SkylineMatrix2D <double>)k.Clone()); } for (int i = 0; i < expansionOrder; i++) { provider.Reset(); coefficientsProvider.CurrentOrder = i; childAnalyzer.BuildMatrices(); matrices[i + 1] = new Dictionary <int, IMatrix2D <double> >(subdomains.Count); foreach (var subdomain in subdomains.Values) { SkylineMatrix2D <double> k = (SkylineMatrix2D <double>)subdomain.Matrix; matrices[i + 1].Add(subdomain.ID, (SkylineMatrix2D <double>)k.Clone()); } } //matrices.Clear(); //provider.Reset(); //coefficientsProvider.CurrentOrder = -1; //childAnalyzer.BuildMatrices(); //foreach (var subdomain in subdomains.Values) //{ // SkylineMatrix2D<double> k = (SkylineMatrix2D<double>)subdomain.Matrix; // matrices.Add(subdomain.ID, (SkylineMatrix2D<double>)k.Clone()); //} //for (int i = 0; i < expansionOrder; i++) //{ // provider.Reset(); // coefficientsProvider.CurrentOrder = i; // childAnalyzer.BuildMatrices(); // foreach (var subdomain in subdomains.Values) // { // SkylineMatrix2D<double> k = (SkylineMatrix2D<double>)subdomain.Matrix; // matrices[subdomain.ID].LinearCombination(new double[] { randomNumbers[currentSimulation][i] }, new IMatrix2D<double>[] { k }); // } //} //foreach (var subdomain in subdomains.Values) // subdomain.Matrix = matrices[subdomain.ID]; }
//private static int[] CalculateRowIndex(Subdomain subdomain) //{ // return CalculateRowIndex(subdomain, subdomain.NodalDOFsDictionary); //} public static SkylineMatrix2D <double> CalculateGlobalMatrix(Subdomain subdomain, Dictionary <int, Dictionary <DOFType, int> > nodalDOFsDictionary, IElementMatrixProvider elementProvider) { // TODO: should encapsulate DOF logic into a separate entity that will manage things if embedded or not (should return element matrix and globaldofs correspondence list var times = new Dictionary <string, TimeSpan>(); var totalStart = DateTime.Now; SkylineMatrix2D <double> K = new SkylineMatrix2D <double>(GlobalMatrixAssemblerSkyline.CalculateRowIndex(subdomain, nodalDOFsDictionary)); times.Add("rowIndexCalculation", DateTime.Now - totalStart); times.Add("element", TimeSpan.Zero); times.Add("addition", TimeSpan.Zero); foreach (Element element in subdomain.ElementsDictionary.Values) { var isEmbeddedElement = element.ElementType is IEmbeddedElement; var elStart = DateTime.Now; IMatrix2D <double> ElementK = elementProvider.Matrix(element); times["element"] += DateTime.Now - elStart; elStart = DateTime.Now; var elementDOFTypes = element.ElementType.DOFEnumerator.GetDOFTypes(element); var matrixAssemblyNodes = element.ElementType.DOFEnumerator.GetNodesForMatrixAssembly(element); int iElementMatrixRow = 0; for (int i = 0; i < elementDOFTypes.Count; i++) { Node nodeRow = matrixAssemblyNodes[i]; foreach (DOFType dofTypeRow in elementDOFTypes[i]) { int dofRow = nodalDOFsDictionary.ContainsKey(nodeRow.ID) == false && isEmbeddedElement ? -1 : nodalDOFsDictionary[nodeRow.ID][dofTypeRow]; if (dofRow != -1) { int iElementMatrixColumn = 0; for (int j = 0; j < elementDOFTypes.Count; j++) { Node nodeColumn = matrixAssemblyNodes[j]; foreach (DOFType dofTypeColumn in elementDOFTypes[j]) { int dofColumn = nodalDOFsDictionary.ContainsKey(nodeColumn.ID) == false && isEmbeddedElement ? -1 : nodalDOFsDictionary[nodeColumn.ID][dofTypeColumn]; if (dofColumn != -1) { int height = dofRow - dofColumn; if (height >= 0) { K.Data[K.RowIndex[dofRow] + height] += ElementK[iElementMatrixRow, iElementMatrixColumn]; } } iElementMatrixColumn++; } } } iElementMatrixRow++; } } times["addition"] += DateTime.Now - elStart; } var totalTime = DateTime.Now - totalStart; return(K); }
public void Initialize() { if (model.SubdomainsDictionary.Count != 1) { throw new InvalidOperationException("Skyline solver operates on one subdomain only."); } foreach (ISolverSubdomain subdomain in subdomainsDictionary.Values) { if (((SkylineMatrix2D <double>)subdomain.Matrix).IsFactorized) { continue; } List <Vector <double> > zems = new List <Vector <double> >(); List <int> zemColumns = new List <int>(); SkylineMatrix2D <double> m = (SkylineMatrix2D <double>)subdomain.Matrix; //StreamWriter sw = File.CreateText(@"d:\KIx1M.txt"); //for (int i = 0; i < m.RowIndex.Length; i++) // sw.WriteLine(m.RowIndex[i]); //sw.Close(); //sw = File.CreateText(@"d:\KData1M.txt"); //for (int i = 0; i < m.Data.Length; i++) // sw.WriteLine(m.Data[i]); //sw.Close(); //sw = File.CreateText(@"d:\f1M.txt"); //for (int i = 0; i < subdomain.RHS.Length; i++) // sw.WriteLine(subdomain.RHS[i]); //sw.Close(); //return; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); ((SkylineMatrix2D <double>)subdomain.Matrix).Factorize(1e-15, zems, zemColumns); stopWatch.Stop(); //StreamWriter sw = File.CreateText(@"c:\factorization.txt"); //sw.WriteLine(stopWatch.ElapsedMilliseconds.ToString()); //sw.Close(); if (zemColumns.Count > 0) { throw new InvalidOperationException("Skyline solver does not operate on singular matrices."); } } //using (var s = File.CreateText("dataFac.txt")) //{ // var m = (SkylineMatrix2D<double>)subdomainsDictionary[1].Matrix; // for (int i = 0; i < m.Data.Length; i++) // s.WriteLine(String.Format("{0:0.#################E+00}", m.Data[i])); //} }
/// <summary> /// Calculates the global stiffness matrix. /// </summary> /// <param name="model">The model.</param> /// <param name="nodalDOFsDictionary">The nodal dofs dictionary.</param> /// <param name="elementProvider">The element provider.</param> /// <returns></returns> public static SkylineMatrix2D CalculateGlobalMatrix(Model model, Dictionary <int, Dictionary <DOFType, int> > nodalDOFsDictionary, ElementStructuralStiffnessProvider elementProvider) { SkylineMatrix2D K = new SkylineMatrix2D(GlobalMatrixAssemblerSkyline.CalculateRowIndex(model, nodalDOFsDictionary)); foreach (Element element in model.ElementsDictionary.Values) { var elStart = DateTime.Now; Matrix2D ElementK = elementProvider.Matrix(element); var elementDOFTypes = element.ElementType.DOFEnumerator.GetDOFTypes(element); var matrixAssemblyNodes = element.ElementType.DOFEnumerator.GetNodesForMatrixAssembly(element); int iElementMatrixRow = 0; for (int i = 0; i < elementDOFTypes.Count; i++) { Node nodeRow = matrixAssemblyNodes[i]; foreach (DOFType dofTypeRow in elementDOFTypes[i]) { int dofRow = nodalDOFsDictionary[nodeRow.ID][dofTypeRow]; if (dofRow != -1) { int iElementMatrixColumn = 0; for (int j = 0; j < elementDOFTypes.Count; j++) { Node nodeColumn = matrixAssemblyNodes[j]; foreach (DOFType dofTypeColumn in elementDOFTypes[j]) { int dofColumn = nodalDOFsDictionary[nodeColumn.ID][dofTypeColumn]; if (dofColumn != -1) { int height = dofRow - dofColumn; if (height >= 0) { K.Data[K.RowIndex[dofRow] + height] += ElementK[iElementMatrixRow, iElementMatrixColumn]; } } iElementMatrixColumn++; } } } iElementMatrixRow++; } } } return(K); }
public void LessenAccuracy(double tolerance) { var valueDictionary = new SortedDictionary <double, List <int> >(); SkylineMatrix2D <double> k = ((SkylineMatrix2D <double>)subdomainsDictionary[1].Matrix); for (int i = 0; i < k.Data.Length; i++) { double difference = Double.MaxValue; double targetValue = k.Data[i]; int index = 0; int count = 0; foreach (var v in valueDictionary.Keys) { if (Math.Abs(k.Data[i] - v) < difference) { difference = Math.Abs(k.Data[i] - v); // Minimize error by taking mean value of these values? targetValue = v; index = count; } count++; } if (difference > tolerance) { valueDictionary.Add(k.Data[i], new List <int>(new[] { i })); } else { valueDictionary[targetValue].Add(i); } } for (int i = 0; i < k.Data.Length; i++) { foreach (var v in valueDictionary.Keys) { if (Math.Abs(k.Data[i] - v) < tolerance) { k.Data[i] = v; break; } } } }
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); } } }
public void Solve() { foreach (ISolverSubdomain subdomain in subdomainsDictionary.Values) { double[] x = ((Vector <double>)subdomain.Solution).Data; SkylineMatrix2D <double> k = ((SkylineMatrix2D <double>)subdomain.Matrix); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); k.Solve(subdomain.RHS, x); stopWatch.Stop(); DestroyAccuracy(subdomain); x = new double[k.Rows]; //LessenAccuracy(1e-7); k.Solve(subdomain.RHS, x); var xVec = new Vector <double>(x); var y = xVec.Norm; //StreamWriter sw = File.CreateText(@"c:\fbsub.txt"); //sw.WriteLine(stopWatch.ElapsedMilliseconds.ToString()); //sw.Close(); } }
private void MultiplyKbi(int subID, double[] vIn, double[] vOut) { SkylineMatrix2D <double> k = (SkylineMatrix2D <double>)subdomainsDictionary[subID].Matrix; var outputDOFs = boundaryDOFsDictionary[subID]; Array.Clear(vOut, 0, outputDOFs.Count); int pos = 0; for (int i = 0; i < k.Rows; i++) { int height = k.RowIndex[i + 1] - k.RowIndex[i]; if (height <= 0) { continue; } int iiIx = outputDOFs.IndexOf(i); if (iiIx < 0) { pos += height; continue; } vOut[iiIx] += k.Data[pos] * vIn[i]; pos++; for (int j = 0; j < height - 1; j++) { int row = i - j - 1; int iiIxRow = outputDOFs.IndexOf(row); if (iiIxRow > -1) { vOut[iiIxRow] += k.Data[pos] * vIn[i]; } vOut[iiIx] += k.Data[pos] * vIn[row]; pos++; } } }
public void BuildMatrices() { if (childAnalyzer == null) { throw new InvalidOperationException("Polynomial chaos analyzer must contain an embedded analyzer."); } if (currentSimulation < 0) { InitializeCoefficientsProvider(); } for (int i = 0; i < coefficientsProvider.NoOfMatrices; i++) { provider.Reset(); coefficientsProvider.CurrentOrder = i; childAnalyzer.BuildMatrices(); matrices[i + 1] = new Dictionary <int, IMatrix2D <double> >(subdomains.Count); foreach (var subdomain in subdomains.Values) { SkylineMatrix2D <double> k = (SkylineMatrix2D <double>)subdomain.Matrix; matrices[i + 1].Add(subdomain.ID, (SkylineMatrix2D <double>)k.Clone()); } } provider.Reset(); coefficientsProvider.CurrentOrder = -1; childAnalyzer.BuildMatrices(); matrices[0] = new Dictionary <int, IMatrix2D <double> >(subdomains.Count); foreach (var subdomain in subdomains.Values) { SkylineMatrix2D <double> k = (SkylineMatrix2D <double>)subdomain.Matrix; matrices[0].Add(subdomain.ID, (SkylineMatrix2D <double>)k.Clone()); } }