/// <summary>
        /// Declaration of the spatial operator
        /// </summary>
        protected override SpatialOperator GetOperatorInstance(int D)
        {
            // instantiate boundary condition mapping
            // ======================================
            boundaryCondMap = new IncompressibleBoundaryCondMap(this.GridData, this.Control.BoundaryValues, PhysicsMode.Incompressible);

            // instantiate operator
            // ====================
            string[] CodName = (new[] { "ResidualMomentumX", "ResidualMomentumY", "ResidualMomentumZ" }).GetSubVector(0, D).Cat("ResidualConti");

            var op = new SpatialOperator(
                __DomainVar: VariableNames.VelocityVector(D).Cat(VariableNames.Pressure),
                __ParameterVar: VariableNames.GravityVector(D),
                __CoDomainVar: CodName,
                QuadOrderFunc: QuadOrderFunc.NonLinear(2));

            op.LinearizationHint = LinearizationHint.GetJacobiOperator;

            // Temporal Operator
            // =================

            var TempOp = new ConstantTemporalOperator(op, 0.0); // init with entire diagonal set to 0.0

            op.TemporalOperator = TempOp;

            for (int d = 0; d < D; d++)
            {
                TempOp.SetDiagonal(CodName[d], Control.Density); // set momentum equation entries to density
            }
            // Pressure Reference
            // ==================

            // if there is no Dirichlet boundary condition,
            // the mean value of the pressure is free:
            op.FreeMeanValue[VariableNames.Pressure] = !boundaryCondMap.DirichletPressureBoundary;

            // Momentum Equation
            // =================

            // convective part:
            {
                for (int d = 0; d < D; d++)
                {
                    var comps = op.EquationComponents[CodName[d]];

                    var ConvBulk = new LocalLaxFriedrichsConvection(D, boundaryCondMap, d, Control.Density);
                    comps.Add(ConvBulk); // bulk component
                }
            }

            // pressure part:
            {
                for (int d = 0; d < D; d++)
                {
                    var comps = op.EquationComponents[CodName[d]];
                    var pres  = new PressureGradientLin_d(d, boundaryCondMap);
                    comps.Add(pres); // bulk component
                }
            }

            // viscous part:
            {
                for (int d = 0; d < D; d++)
                {
                    var comps = op.EquationComponents[CodName[d]];

                    double penalty_bulk = this.Control.PenaltySafety;

                    var Visc = new swipViscosity_Term1(penalty_bulk, d, D, boundaryCondMap,
                                                       ViscosityOption.ConstantViscosity,
                                                       constantViscosityValue: Control.Viscosity);
                    comps.Add(Visc); // bulk component GradUTerm
                }
            }


            // Continuity equation
            // ===================
            {
                for (int d = 0; d < D; d++)
                {
                    var src = new Divergence_DerivativeSource(d, D);
                    var flx = new Divergence_DerivativeSource_Flux(d, boundaryCondMap);
                    op.EquationComponents[CodName[D]].Add(src);
                    op.EquationComponents[CodName[D]].Add(flx);
                }


                //IBM_Op.EquationComponents["div"].Add(new PressureStabilization(1, 1.0 / this.Control.PhysicalParameters.mu_A));
            }

            // Gravity parameter
            // =================

            op.ParameterFactories.Add(delegate(IReadOnlyDictionary <string, DGField> DomainVarFields) {
                return(D.ForLoop(d => (VariableNames.Gravity_d(d), this.Gravity[d] as DGField)));
            });


            // commit & return
            // ===============
            op.Commit();
            return(op);
        }