/// <summary>
        /// defines the problem matrix
        /// </summary>
        public void Init(MultigridOperator op)
        {
            this.m_MgOperator = op;
            var Mtx   = op.OperatorMatrix;
            var MgMap = op.Mapping;

            viz = new MGViz(op);

            if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Row partitioning mismatch.");
            }
            if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning))
            {
                throw new ArgumentException("Column partitioning mismatch.");
            }

            MxxHistory.Clear();
            SolHistory.Clear();

            double Dim = MgMap.ProblemMapping.GridDat.SpatialDimension;

            // set operator
            // ============
            if (op.CoarserLevel == null)
            {
                throw new NotSupportedException("Multigrid algorithm cannot be used as a solver on the finest level.");
            }
            this.OpMatrix = Mtx;


            // initiate coarser level
            // ======================
            if (this.CoarserLevelSolver == null)
            {
                throw new NotSupportedException("Missing coarse level solver.");
            }
            this.CoarserLevelSolver.Init(op.CoarserLevel);


            // init smoother
            // =============
            if (PreSmoother != null)
            {
                PreSmoother.Init(op);
            }
            if (PostSmoother != null && !object.ReferenceEquals(PreSmoother, PostSmoother))
            {
                PostSmoother.Init(op);
            }
        }
        /// <summary>
        /// defines the problem matrix
        /// </summary>
        public void Init(MultigridOperator op)
        {
            using (var tr = new FuncTrace()) {
                this.m_MgOperator = op;
                var Mtx   = op.OperatorMatrix;
                var MgMap = op.Mapping;
                //if(op.LevelIndex == 0)
                //    viz = new MGViz(op);

                if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning))
                {
                    throw new ArgumentException("Row partitioning mismatch.");
                }
                if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning))
                {
                    throw new ArgumentException("Column partitioning mismatch.");
                }

                MxxHistory.Clear();
                SolHistory.Clear();


                // set operator
                // ============
                this.OpMatrix = Mtx;


                // initiate coarser level
                // ======================
                if (this.CoarserLevelSolver == null)
                {
                    //throw new NotSupportedException("Missing coarse level solver.");
                    Console.WriteLine("OrthonormalizationMultigrid: running without coarse solver.");
                }
                else
                {
                    if (op.CoarserLevel != null)
                    {
                        this.CoarserLevelSolver.Init(op.CoarserLevel);
                        CoarseOnLovwerLevel = true;
                    }
                    else
                    {
                        Console.WriteLine("OrthonormalizationMultigrid: running coarse solver on same level.");
                        this.CoarserLevelSolver.Init(op);
                        CoarseOnLovwerLevel = false;
                    }
                }

                // init smoother
                // =============
                if (PreSmoother != null)
                {
                    PreSmoother.Init(op);
                }
                if (PostSmoother != null && !object.ReferenceEquals(PreSmoother, PostSmoother))
                {
                    PostSmoother.Init(op);
                }
            }
        }