예제 #1
0
        /// <summary>
        /// Compress Z submatrix with multilevel subdivision
        /// </summary>
        /// <param name="basicFuncBoxes">Information about the location of basis functions in boxes at different levels</param>
        /// <param name="ix_s">x-index of source box at level l</param>
        /// <param name="iy_s">y-index of source box at level l</param>
        /// <param name="iz_s">z-index of source box at level l</param>
        /// <param name="ix_f">x-index of field box at level l</param>
        /// <param name="iy_f">y-index of field box at level l</param>
        /// <param name="iz_f">z-index of field box at level l</param>
        /// <param name="l">Current level</param>
        /// <param name="L">Maximum level to end multilevel subdivion</param>
        /// <param name="ACA_thres">Relative error threshold to stop adding rows and columns in ACA iteration</param>
        /// <param name="Z_comp">compressed matrix</param>                          
        public static void MultilevelCompres(BasicFuncBoxes basicFuncBoxes, double ix_s, double iy_s, double iz_s, double ix_f, double iy_f, double iz_f, int l, double L, double ACA_thres,ref NewSparseMatrix Z_comp)
        {
            bool sym_source_field = true;
            //NewSparseMatrix Z_comp = new NewSparseMatrix();

            for (double xchs = 0; xchs <= 1; xchs++)
            {
                for (double ychs = 0; ychs <= 1; ychs++)
                {
                    for (double zchs = 0; zchs <= 1; zchs++)
                    {
                        // x-index of source child box at level l+1
                        double ix_chs = ix_s * 2 + xchs;
                        // y-index of source child box at level l+1
                        double iy_chs = iy_s * 2 + ychs;
                        // z-index of source child box at level l+1
                        double iz_chs = iz_s * 2 + zchs;

                        //Find indices of basis functions in source child box
                        List<int> m = new List<int>();
                        for (int i = 0; i < basicFuncBoxes.X.RowCount; i++)
                        {
                            if (basicFuncBoxes.X[i, l] == ix_chs && basicFuncBoxes.Y[i, l] == iy_chs && basicFuncBoxes.Z[i, l] == iz_chs)
                            {
                                m.Add(i);
                            }
                        }
                        if (m.Count == 0)
                        {
                            continue;
                        }

                        //Subdivide field box and process children
                        for (double xchf = 0; xchf <= 1; xchf++)
                        {
                            for (double ychf = 0; ychf <= 1; ychf++)
                            {
                                for (double zchf = 0; zchf <= 1; zchf++)
                                {
                                    //x-index of field child box at level l+1
                                    double ix_chf = ix_f * 2 + xchf;
                                    // y-index of field child box at level l+1
                                    double iy_chf = iy_f * 2 + ychf;
                                    // z-index of field child box at level l+1
                                    double iz_chf = iz_f * 2 + zchf;

                                    //Find indices of testing functions in field child box
                                    List<int> n = new List<int>();
                                    for (int i = 0; i < basicFuncBoxes.X.RowCount; i++)
                                    {
                                        if (basicFuncBoxes.X[i, l] == ix_chf && basicFuncBoxes.Y[i, l] == iy_chf && basicFuncBoxes.Z[i, l] == iz_chf)
                                        {
                                            n.Add(i);
                                        }
                                    }
                                    if (n.Count == 0)
                                    {
                                        continue;
                                    }

                                    // Here we have a pair of non-empty source and field boxes
                                    if (Math.Abs(ix_chs - ix_chf) > 1 || Math.Abs(iy_chs - iy_chf) > 1 || Math.Abs(iz_chs - iz_chf) > 1)
                                    {// Far-field boxes
                                        if (sym_source_field == true)
                                        {
                                            // Symmetric source-field field-source
                                            // interactions are only computed once.
                                            if (ix_chs - ix_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf > 0)
                                            {
                                                //[U,V] = ACA(ACA_thres, m,n, OG_data,EM_data);
                                                DenseMatrix U = new DenseMatrix(1, 1);
                                                DenseMatrix V = new DenseMatrix(1, 1);
                                                Tuple<Matrix,Matrix> r = Aca(ACA_thres, m, n, U, V);
                                                //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',1,'self',0,'Z',[] ,'U',U,'V',V);
                                                Z_comp.Add(new ACAStruct(m,n,new DenseMatrix(1,1),r.Item1,r.Item2,1,0));
                                            }
                                        }
                                        else
                                        {
                                            // We need to compute all because there is
                                            // not symmetric interactions
                                            DenseMatrix U = new DenseMatrix(1, 1);
                                            DenseMatrix V = new DenseMatrix(1, 1);
                                            //[U,V] = ACA(ACA_thres, m,n, OG_data,EM_data);
                                            Tuple<Matrix, Matrix> r = Aca(ACA_thres, m, n, U, V);
                                            //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',1,'self',0,'Z',[] ,'U',U,'V',V);
                                            Z_comp.Add(new ACAStruct(m, n, new DenseMatrix(1, 1), r.Item1, r.Item2, 1, 0));
                                        }
                                    }
                                    else // Near-field boxes
                                    {
                                         double self = 0;
                                         if (l + 1 == L)
                                         {
                                             if (sym_source_field == true)
                                             {
                                                 // Symmetric source-field field-source
                                                 // interactions are only computed once.
                                                 if (ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf == 0)
                                                 {
                                                     // Self-interactions
                                                     self = 1;
                                                     // Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',0,'self',self,'Z', user_impedance(m,n,OG_data,EM_data),'U',[],'V',[]);
                                                     Z_comp.Add(new ACAStruct(m, n, UserImpedance(m, n), new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, self));
                                                 }
                                                 if (ix_chs - ix_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf > 0)
                                                 {
                                                     //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',0,'self',self,'Z', user_impedance(m,n,OG_data,EM_data),'U',[],'V',[]);
                                                     Z_comp.Add(new ACAStruct(m, n, UserImpedance(m, n), new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, self));
                                                 }

                                             }
                                             else
                                             {
                                                 // We need to compute all because there are
                                                 // not symmetric interactions
                                                 if (ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf == 0)
                                                 {
                                                     // Self-interactions
                                                     self = 1;
                                                 }
                                                 //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',0,'self',self,'Z', user_impedance(m,n,OG_data,EM_data),'U',[],'V',[]);
                                                 Z_comp.Add(new ACAStruct(m, n, UserImpedance(m, n), new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, (int)self));
                                             }

                                         }
                                         else
                                         {
                                             //Z_comp = [Z_comp multilevel_compress(basis_func_boxes,ix_chs,iy_chs,iz_chs,ix_chf,iy_chf,iz_chf,l+1,L,ACA_thres,OG_data,EM_data)];
                                                              //multilevel_compress(basis_func_boxes,ix_s,iy_s,iz_s,ix_f,iy_f,iz_f,l,L,ACA_thres,OG_data,EM_data)
                                             MultilevelCompres(basicFuncBoxes,ix_chs,iy_chs,iz_chs,ix_chf,iy_chf,iz_chf,l+1,L,ACA_thres,ref Z_comp);

                                         }
                                    }

                                }
                            }
                        }
                    }
                }
            }

            //return Z_comp;
        }
예제 #2
0
        /// <summary>
        /// Compute indices of boxes at all levels for each basis function
        /// </summary>
        /// <param name="rcx">x-coordinates of basis functions centers</param>
        /// <param name="rcy">y-coordinates of basis functions centers</param>
        /// <param name="rcz">z-coordinates of basis functions centers</param>
        /// <param name="N">Number of basis functions (length of rcx, rcy, and rcz)</param>
        /// <param name="finest_level_size">size of finest level in multilevel subdivision</param>
        /// <returns>
        /// Matrix with one column per level in multilevel subdivision
        /// Columns contain the box index in which a basis function is located                    Row index is the basis function index
        /// </returns>
        public static BasicFuncBoxes PrepareMultilevel(Vector rcx, Vector rcy, Vector rcz, int N, double finest_level_size)
        {
            double xmax = rcx.Max(); double xmin = rcx.Min();
            double ymax = rcy.Max(); double ymin = rcy.Min();
            double zmax = rcz.Max(); double zmin = rcz.Min();

            int Lx = (int)Math.Ceiling(Math.Log((xmax - xmin) / (finest_level_size)) / Math.Log(2));
            int Ly = (int)Math.Ceiling(Math.Log((ymax - ymin) / (finest_level_size)) / Math.Log(2));
            int Lz = (int)Math.Ceiling(Math.Log((zmax - zmin) / (finest_level_size)) / Math.Log(2));
            int L = (int)Math.Max(Lx, Math.Max(Ly, Lz));

            double box_size_x = (xmax - xmin) * (1 + 1e-3);
            double box_size_y = (ymax - ymin) * (1 + 1e-3);
            double box_size_z = (zmax - zmin) * (1 + 1e-3);
            double box_size = Math.Max(box_size_x, Math.Max(box_size_y, box_size_z));

            BasicFuncBoxes basicFuncBoxes = new BasicFuncBoxes(N, L);

            for (int i = 0; i < L; i++)
            {
                box_size = box_size / 2;

                Vector tempVx = new DenseVector(rcx.Count);
                for (int j = 0; j < rcx.Count; j++)
                {
                    tempVx[j] = Math.Floor((rcx[j] - xmin) / box_size);
                }

                Vector tempVy = new DenseVector(rcy.Count);
                for (int j = 0; j < rcy.Count; j++)
                {
                    tempVy[j] = Math.Floor((rcy[j] - ymin) / box_size);
                }

                Vector tempVz = new DenseVector(rcz.Count);
                for (int j = 0; j < rcz.Count; j++)
                {
                    tempVz[j] = Math.Floor((rcz[j] - zmin) / box_size);
                }

                basicFuncBoxes.X.SetColumn(i, tempVx);
                basicFuncBoxes.Y.SetColumn(i, tempVy);
                basicFuncBoxes.Z.SetColumn(i, tempVz);
            }

            return basicFuncBoxes;
        }
예제 #3
0
        static void Main(string[] args)
        {
            BasicFuncBoxes b = new BasicFuncBoxes(10, 10);

            double finest_level_size = 0.25; // Size of finest level (lambdas) of multilevel subdivision
            double ACA_thres = 1e-3;       // Relative error threshold to stop adding rows and columns in ACA iteration
            double precon_radius = 0.15;   // Precondioner size (meters): elements of Z with R < precon_radius
            double tol = 1e-2;             // Convergence tolerance in iterative solver
            double maxN_Z = 5000;

            StreamReader xRead = new StreamReader("X.txt");
            StreamReader yRead = new StreamReader("Y.txt");
            StreamReader zRead = new StreamReader("Z.txt");

            StreamReader jRead = new StreamReader("J.txt");

            Vector rcx;
            Vector rcy;
            Vector rcz;

            String str = xRead.ReadToEnd();

            List<double> lst = new List<double>();

            foreach (string s in str.Split('\t'))
            {
                lst.Add(double.Parse(s));
            }

            rcx = new DenseVector(lst.ToArray());

            str = yRead.ReadToEnd();
            lst.Clear();

            foreach (string s in str.Split('\t'))
            {
                lst.Add(double.Parse(s));
            }

            rcy = new DenseVector(lst.ToArray());

            str = zRead.ReadToEnd();
            lst.Clear();

            foreach (string s in str.Split('\t'))
            {
                lst.Add(double.Parse(s));
            }

            rcz = new DenseVector(lst.ToArray());

            int N = 3072;
            //Fill Z matrix
            if( N <= maxN_Z)
            {
               //Z = user_impedance(1:N, 1:N, OG_data,EM_data);
               List<int> n = new List<int>(N);
               for (int i = 0; i < N; i++)
               {
                   n.Add(i);
               }
               Matrix Z = ACA.UserImpedance(n,n);
               // Copy of uncompressed Z for iterative solver
               //Z_uncomp = cell(1,1);
               NewSparseMatrix Z_uncomp = new NewSparseMatrix();
               Z_uncomp.Add(new ACAStruct(n, n, Z, new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, 1));
            }
            //CHECKED - OK everything before works well
            BasicFuncBoxes bfb = ACA.PrepareMultilevel(rcx, rcy, rcz, N, finest_level_size);
            NewSparseMatrix Z_comp = new NewSparseMatrix();
            ACA.MultilevelCompres(bfb, 0, 0, 0, 0, 0, 0, 0, bfb.L, ACA_thres, ref Z_comp);

            //testing Multiply(matvec in mathlab)
            Vector J = new DenseVector(3072);
            int k = 0;
            while (jRead.EndOfStream == false)
            {
                string s = jRead.ReadLine();
                string[] a = s.Split(' ');
                int p = 3;
                if (a.Length == 5) p = 2;
                J[k] = double.Parse(a[p].Replace('.',','));
                k++;
            }

            Vector r = Z_comp.Multiply(J, true);
        }