/// <summary>
        ///
        /// </summary>
        /// <param name="XOp"></param>
        /// <param name="CodName"></param>
        /// <param name="_D"></param>
        /// <param name="BcMap"></param>
        /// <param name="config"></param>
        /// <param name="LsTrk"></param>
        public static void AddInterfaceContinuityEq(XSpatialOperatorMk2 XOp, IXNSE_Configuration config, int D, LevelSetTracker LsTrk)
        {
            // check input
            if (XOp.IsCommited)
            {
                throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed");
            }

            string CodName = EquationNames.ContinuityEquation;

            if (!XOp.CodomainVar.Contains(CodName))
            {
                throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator");
            }

            PhysicalParameters   physParams = config.getPhysParams;
            DoNotTouchParameters dntParams  = config.getDntParams;

            // set species arguments
            double rhoA = physParams.rho_A;
            double rhoB = physParams.rho_B;

            // set components
            var comps = XOp.EquationComponents[CodName];

            var divPen = new Operator.Continuity.DivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, config.isMatInt, dntParams.ContiSign, dntParams.RescaleConti);

            comps.Add(divPen);
            //var stabint = new PressureStabilizationAtLevelSet(LsTrk, dntParams.PresPenalty2, physParams.reynolds_A, physParams.reynolds_B);
            //comps.Add(stabint);
        }
Esempio n. 2
0
        /// <summary>
        /// clone
        /// </summary>
        public object Clone()
        {
            var cl = new DoNotTouchParameters()
            {
                CellAgglomerationThreshold = this.CellAgglomerationThreshold,
                ContiSign                = this.ContiSign,
                RescaleConti             = this.RescaleConti,
                LFFA                     = this.LFFA,
                LFFB                     = this.LFFB,
                PenaltySafety            = this.PenaltySafety,
                SurfStressTensor         = this.SurfStressTensor,
                SST_isotropicMode        = this.SST_isotropicMode,
                UseLevelSetStabilization = this.UseLevelSetStabilization,
                UseWeightedAverages      = this.UseWeightedAverages,
                ViscosityMode            = this.ViscosityMode,
                //ViscosityImplementation = this.ViscosityImplementation,
                UseGhostPenalties   = this.UseGhostPenalties,
                FilterConfiguration = this.FilterConfiguration,
                GNBC_Localization   = this.GNBC_Localization,
                GNBC_SlipLength     = this.GNBC_SlipLength,
                //viscoelastic LDG Stuff:
                ObjectiveParam = this.ObjectiveParam,
                alpha          = this.alpha,
                Penalty1       = this.Penalty1,
                Penalty2       = this.Penalty2,
                PresPenalty1   = this.PresPenalty1,
                PresPenalty2   = this.PresPenalty2,
                StressPenalty  = this.StressPenalty
            };

            return(cl);
        }
        //====================
        // Continuity equation
        //====================
        #region conti

        /// <summary>
        ///
        /// </summary>
        /// <param name="XOp"></param>
        /// <param name="config"></param>
        /// <param name="D"></param>
        /// <param name="spcName"></param>
        /// <param name="spcId"></param>
        /// <param name="BcMap"></param>
        public static void AddSpeciesContinuityEq(XSpatialOperatorMk2 XOp, INSE_Configuration config, int D,
                                                  string spcName, SpeciesId spcId, IncompressibleMultiphaseBoundaryCondMap BcMap)
        {
            // check input
            if (XOp.IsCommited)
            {
                throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed");
            }

            string CodName = EquationNames.ContinuityEquation;

            if (!XOp.CodomainVar.Contains(CodName))
            {
                throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator");
            }

            PhysicalParameters   physParams = config.getPhysParams;
            DoNotTouchParameters dntParams  = config.getDntParams;

            // set species arguments
            double rhoSpc;

            switch (spcName)
            {
            case "A": { rhoSpc = physParams.rho_A; break; }

            case "B": { rhoSpc = physParams.rho_B; break; }

            default: throw new ArgumentException("Unknown species.");
            }

            // set components
            var comps = XOp.EquationComponents[CodName];

            for (int d = 0; d < D; d++)
            {
                var src = new Operator.Continuity.DivergenceInSpeciesBulk_Volume(d, D, spcName, rhoSpc, dntParams.ContiSign, dntParams.RescaleConti);
                comps.Add(src);
                var flx = new Operator.Continuity.DivergenceInSpeciesBulk_Edge(d, BcMap, spcName, spcId, rhoSpc, dntParams.ContiSign, dntParams.RescaleConti);
                comps.Add(flx);
                //var stab = new PressureStabilizationInBulk(dntParams.PresPenalty2, physParams.reynolds_A, physParams.reynolds_B, spcName, spcId);
                //comps.Add(stab);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// clone
        /// </summary>
        public object Clone()
        {
            var cl = new DoNotTouchParameters()
            {
                CellAgglomerationThreshold = this.CellAgglomerationThreshold,
                ContiSign               = this.ContiSign,
                RescaleConti            = this.RescaleConti,
                LFFA                    = this.LFFA,
                LFFB                    = this.LFFB,
                PenaltySafety           = this.PenaltySafety,
                SurfStressTensor        = this.SurfStressTensor,
                SST_isotropicMode       = this.SST_isotropicMode,
                ViscosityMode           = this.ViscosityMode,
                ViscosityImplementation = this.ViscosityImplementation,
                UseGhostPenalties       = this.UseGhostPenalties,
                FilterConfiguration     = this.FilterConfiguration
            };

            return(cl);
        }
        //=======================
        // Navier Stokes equation
        //=======================
        #region nse

        /// <summary>
        ///
        /// </summary>
        /// <param name="XOp"></param>
        /// <param name="d"></param>
        /// <param name="D"></param>
        /// <param name="spcName"></param>
        /// <param name="spcId"></param>
        /// <param name="BcMap"></param>
        /// <param name="config"></param>
        /// <param name="LsTrk"></param>
        /// <param name="U0meanrequired"></param>
        public static void AddSpeciesNSE_component(XSpatialOperatorMk2 XOp, INSE_Configuration config, int d, int D, string spcName, SpeciesId spcId,
                                                   IncompressibleMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk, out bool U0meanrequired)
        {
            // check input
            if (XOp.IsCommited)
            {
                throw new InvalidOperationException("Spatial Operator is already committed. Adding of new components is not allowed");
            }

            string CodName = EquationNames.MomentumEquationComponent(d);

            if (!XOp.CodomainVar.Contains(CodName))
            {
                throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator");
            }

            PhysicalParameters   physParams = config.getPhysParams;
            DoNotTouchParameters dntParams  = config.getDntParams;

            // set species arguments
            double rhoSpc, LFFSpc, muSpc;

            switch (spcName)
            {
            case "A": { rhoSpc = physParams.rho_A; LFFSpc = dntParams.LFFA; muSpc = physParams.mu_A; break; }

            case "B": { rhoSpc = physParams.rho_B; LFFSpc = dntParams.LFFB; muSpc = physParams.mu_B; break; }

            default: throw new ArgumentException("Unknown species.");
            }

            // set components
            var comps = XOp.EquationComponents[CodName];

            // convective operator
            // ===================
            U0meanrequired = false;
            if (physParams.IncludeConvection && config.isTransport)
            {
                var conv = new Operator.Convection.ConvectionInSpeciesBulk_LLF(D, BcMap, spcName, spcId, d, rhoSpc, LFFSpc, LsTrk);
                comps.Add(conv);
                U0meanrequired = true;
            }

            // pressure gradient
            // =================
            if (config.isPressureGradient)
            {
                var pres = new Operator.Pressure.PressureInSpeciesBulk(d, BcMap, spcName, spcId);
                comps.Add(pres);

                //problably necessary for LDG Simulation. Only one species parameter reynoldsA!!!!!!
                //var presStab = new PressureStabilizationInBulk(dntParams.PresPenalty2, physParams.reynolds_A, spcName, spcId);
                //comps.Add(presStab);
            }

            // viscous operator
            // ================
            if (config.isViscous && !(muSpc == 0.0))
            {
                double penalty = dntParams.PenaltySafety;
                switch (dntParams.ViscosityMode)
                {
                case ViscosityMode.Standard:
                case ViscosityMode.TransposeTermMissing: {
                    // Bulk operator:
                    var Visc1 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm(
                        dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                        BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B);
                    comps.Add(Visc1);

                    if (dntParams.UseGhostPenalties)
                    {
                        var Visc1Penalty = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm(
                            penalty, 0.0,
                            BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B);
                        XOp.GhostEdgesOperator.EquationComponents[CodName].Add(Visc1Penalty);
                    }

                    break;
                }

                case ViscosityMode.FullySymmetric: {
                    // Bulk operator
                    var Visc1 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm(
                        dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                        BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B);
                    comps.Add(Visc1);

                    var Visc2 = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUtranspTerm(
                        dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                        BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B);
                    comps.Add(Visc2);


                    if (dntParams.UseGhostPenalties)
                    {
                        var Visc1Penalty = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUTerm(
                            penalty, 0.0,
                            BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B);
                        var Visc2Penalty = new Operator.Viscosity.ViscosityInSpeciesBulk_GradUtranspTerm(
                            penalty, 0.0,
                            BcMap, spcName, spcId, d, D, physParams.mu_A, physParams.mu_B);

                        XOp.GhostEdgesOperator.EquationComponents[CodName].Add(Visc1Penalty);
                        XOp.GhostEdgesOperator.EquationComponents[CodName].Add(Visc2Penalty);
                    }

                    break;
                }

                case ViscosityMode.Viscoelastic: {
                    //set species arguments
                    double ReSpc, betaSpc;
                    switch (spcName)
                    {
                    case "A": { ReSpc = physParams.reynolds_A; betaSpc = physParams.beta_a; break; }

                    case "B": { ReSpc = physParams.reynolds_B; betaSpc = physParams.beta_b; break; }

                    default: throw new ArgumentException("Unknown species.");
                    }

                    // Bulk operator:
                    var Visc1 = new Operator.Viscosity.DimensionlessViscosityInSpeciesBulk_GradUTerm(
                        dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                        BcMap, spcName, spcId, d, D, physParams.reynolds_A / physParams.beta_a, physParams.reynolds_B / physParams.beta_b);
                    comps.Add(Visc1);

                    var Visc2 = new Operator.Viscosity.DimensionlessViscosityInSpeciesBulk_GradUtranspTerm(
                        dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                        BcMap, spcName, spcId, d, D, physParams.reynolds_A / physParams.beta_a, physParams.reynolds_B / physParams.beta_b);
                    comps.Add(Visc2);

                    var div = new StressDivergenceInBulk(d, BcMap, ReSpc, dntParams.Penalty1, dntParams.Penalty2, spcName, spcId);
                    comps.Add(div);

                    break;
                }


                default:
                    throw new NotImplementedException();
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="XOp"></param>
        /// <param name="config"></param>
        /// <param name="d"></param>
        /// <param name="D"></param>
        /// <param name="BcMap"></param>
        /// <param name="LsTrk"></param>
        /// <param name="degU"></param>
        /// <param name="NormalsRequired"></param>
        /// <param name="CurvatureRequired"></param>
        public static void AddSurfaceTensionForce_component(XSpatialOperatorMk2 XOp, IXNSE_Configuration config, int d, int D,
                                                            IncompressibleMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk, int degU,
                                                            out bool NormalsRequired, out bool CurvatureRequired)
        {
            // check input
            if (XOp.IsCommited)
            {
                throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed");
            }

            string CodName = EquationNames.MomentumEquationComponent(d);

            if (!XOp.CodomainVar.Contains(CodName))
            {
                throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator");
            }

            PhysicalParameters   physParams = config.getPhysParams;
            DoNotTouchParameters dntParams  = config.getDntParams;

            // set arguments
            double sigma = physParams.Sigma;

            // set components
            //var comps = XOp.SurfaceElementOperator.EquationComponents[CodName];

            // surface stress tensor
            // =====================
            NormalsRequired   = false;
            CurvatureRequired = false;
            if (config.isPressureGradient && physParams.Sigma != 0.0)
            {
                // isotropic part of the surface stress tensor
                // ===========================================

                if (dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux ||
                    dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Local ||
                    dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine)
                {
                    if (dntParams.SST_isotropicMode != SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine)
                    {
                        IEquationComponent G = new SurfaceTension_LaplaceBeltrami_Surface(d, sigma * 0.5);
                        XOp.SurfaceElementOperator.EquationComponents[CodName].Add(G);
                        IEquationComponent H = new SurfaceTension_LaplaceBeltrami_BndLine(d, sigma * 0.5, dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux);
                        XOp.SurfaceElementOperator.EquationComponents[CodName].Add(H);
                    }
                    else
                    {
                        IEquationComponent isoSurfT = new IsotropicSurfaceTension_LaplaceBeltrami(d, D, sigma * 0.5, BcMap.EdgeTag2Type, BcMap, physParams.theta_e, physParams.betaL);
                        XOp.SurfaceElementOperator.EquationComponents[CodName].Add(isoSurfT);
                    }
                    NormalsRequired = true;
                }
                else if (dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Projected ||
                         dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_ClosestPoint ||
                         dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_LaplaceBeltramiMean ||
                         dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier)
                {
                    XOp.EquationComponents[CodName].Add(new CurvatureBasedSurfaceTension(d, D, LsTrk, sigma));

                    CurvatureRequired = true;
                }
                else
                {
                    throw new NotImplementedException("Not implemented.");
                }


                // dynamic part of the surface stress tensor
                // =========================================

                if (dntParams.SurfStressTensor != SurfaceSressTensor.Isotropic)
                {
                    double muI    = physParams.mu_I;
                    double lamI   = physParams.lambda_I;
                    double lamI_t = (physParams.lambdaI_tilde < 0) ? (lamI - muI) : physParams.lambdaI_tilde;

                    double penalty_base = (degU + 1) * (degU + D) / D;
                    double penalty      = penalty_base * dntParams.PenaltySafety;

                    // surface dilatational viscosity
                    if (dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceDivergence ||
                        dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven)
                    {
                        var surfDiv = new BoussinesqScriven_SurfaceVelocityDivergence(d, D, lamI_t * 0.5, penalty, BcMap.EdgeTag2Type, true);
                        XOp.SurfaceElementOperator.EquationComponents[CodName].Add(surfDiv);
                    }

                    // surface shear viscosity
                    if (dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceRateOfDeformation ||
                        dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit ||
                        dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven)
                    {
                        var surfDeformRate = new BoussinesqScriven_SurfaceDeformationRate_GradU(d, D, muI * 0.5, penalty, true, dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit);
                        XOp.SurfaceElementOperator.EquationComponents[CodName].Add(surfDeformRate);

                        if (dntParams.SurfStressTensor != SurfaceSressTensor.SemiImplicit)
                        {
                            var surfDeformRateT = new BoussinesqScriven_SurfaceDeformationRate_GradUTranspose(d, D, muI * 0.5, penalty, true);
                            XOp.SurfaceElementOperator.EquationComponents[CodName].Add(surfDeformRateT);
                        }
                    }
                }


                // stabilization
                // =============

                if (dntParams.UseLevelSetStabilization)
                {
                    XOp.EquationComponents[CodName].Add(new LevelSetStabilization(d, D, LsTrk));
                }
            }


            // artificial surface tension force
            // ================================

            if (config.isPressureGradient && physParams.useArtificialSurfaceForce)
            {
                XOp.EquationComponents[CodName].Add(new SurfaceTension_ArfForceSrc(d, D, LsTrk));
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="XOp"></param>
        /// <param name="config"></param>
        /// <param name="d"></param>
        /// <param name="D"></param>
        /// <param name="BcMap"></param>
        /// <param name="LsTrk"></param>
        public static void AddInterfaceNSE_component(XSpatialOperatorMk2 XOp, IXNSE_Configuration config, int d, int D,
                                                     IncompressibleMultiphaseBoundaryCondMap BcMap, LevelSetTracker LsTrk)
        {
            // check input
            if (XOp.IsCommited)
            {
                throw new InvalidOperationException("Spatial Operator is already comitted. Adding of new components is not allowed");
            }

            string CodName = EquationNames.MomentumEquationComponent(d);

            if (!XOp.CodomainVar.Contains(CodName))
            {
                throw new ArgumentException("CoDomain variable \"" + CodName + "\" is not defined in Spatial Operator");
            }

            PhysicalParameters   physParams = config.getPhysParams;
            DoNotTouchParameters dntParams  = config.getDntParams;

            // set species arguments
            double rhoA = physParams.rho_A;
            double rhoB = physParams.rho_B;
            double LFFA = dntParams.LFFA;
            double LFFB = dntParams.LFFB;
            double muA  = physParams.mu_A;
            double muB  = physParams.mu_B;

            //viscoelastic
            double reynoldsA = physParams.reynolds_A;
            double reynoldsB = physParams.reynolds_B;
            double betaA     = physParams.beta_a;
            double betaB     = physParams.beta_b;

            double[] penalty1 = dntParams.Penalty1;
            double   penalty2 = dntParams.Penalty2;


            // set components
            var comps = XOp.EquationComponents[CodName];

            // convective operator
            // ===================
            if (physParams.IncludeConvection && config.isTransport)
            {
                var conv = new Operator.Convection.ConvectionAtLevelSet_LLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, physParams.Material, BcMap, config.isMovingMesh);
                comps.Add(conv);
            }

            // pressure gradient
            // =================
            if (config.isPressureGradient)
            {
                var presLs = new Operator.Pressure.PressureFormAtLevelSet(d, D, LsTrk);
                comps.Add(presLs);
            }

            // viscous operator
            // ================
            if (config.isViscous && (!(muA == 0.0) && !(muB == 0.0)))
            {
                double penalty = dntParams.PenaltySafety;
                switch (dntParams.ViscosityMode)
                {
                case ViscosityMode.Standard:
                    comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, true));
                    break;

                case ViscosityMode.TransposeTermMissing:
                    comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, false));
                    break;

                case ViscosityMode.FullySymmetric:
                    comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, dntParams.UseWeightedAverages));
                    break;

                case ViscosityMode.Viscoelastic:
                    //comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, 1 / reynoldsA, 1 / reynoldsB, penalty * 1.0, d, false));

                    comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, betaA / reynoldsA, betaB / reynoldsB, penalty, d, dntParams.UseWeightedAverages));
                    comps.Add(new Operator.Viscosity.StressDivergenceAtLevelSet(LsTrk, reynoldsA, reynoldsB, penalty1, penalty2, d, dntParams.UseWeightedAverages));

                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
Esempio n. 8
0
        public OperatorFactory(
            OperatorConfiguration config,
            LevelSetTracker _LsTrk,
            int _HMFdegree,
            int degU,
            IncompressibleMultiphaseBoundaryCondMap BcMap,
            bool _movingmesh,
            bool _evaporation,
            bool _staticInt)
        {
            // variable names
            // ==============
            D          = _LsTrk.GridDat.SpatialDimension;
            this.LsTrk = _LsTrk;
            //this.momentFittingVariant = momentFittingVariant;
            this.HMFDegree           = _HMFdegree;
            this.dntParams           = config.dntParams.CloneAs();
            this.physParams          = config.physParams.CloneAs();
            this.UseExtendedVelocity = config.UseXDG4Velocity;
            this.movingmesh          = _movingmesh;
            this.evaporation         = _evaporation;

            // test input
            // ==========
            {
                if (config.DomBlocks.GetLength(0) != 2 || config.CodBlocks.GetLength(0) != 2)
                {
                    throw new ArgumentException();
                }
                if (config.physParams.mu_A == 0.0 && config.physParams.mu_B == 0.0)
                {
                    muIs0 = true;
                }
                else
                {
                    if (config.physParams.mu_A <= 0)
                    {
                        throw new ArgumentException();
                    }
                    if (config.physParams.mu_B <= 0)
                    {
                        throw new ArgumentException();
                    }
                }

                if (config.physParams.rho_A <= 0)
                {
                    throw new ArgumentException();
                }
                if (config.physParams.rho_B <= 0)
                {
                    throw new ArgumentException();
                }

                if (_LsTrk.SpeciesNames.Count != 2)
                {
                    throw new ArgumentException();
                }
                if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B")))
                {
                    throw new ArgumentException();
                }
            }


            // full operator:
            CodName = ((new string[] { "momX", "momY", "momZ" }).GetSubVector(0, D)).Cat("div");
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(D),
                VariableNames.Velocity0MeanVector(D),
                "Curvature",
                (new string[] { "surfForceX", "surfForceY", "surfForceZ" }).GetSubVector(0, D),
                (new string[] { "NX", "NY", "NZ" }).GetSubVector(0, D),
                (new string[] { "GradTempX", "GradTempY", "GradTempZ" }.GetSubVector(0, D)),
                VariableNames.Temperature,
                "DisjoiningPressure");
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure);

            // selected part:
            if (config.CodBlocks[0])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D));
            }
            if (config.CodBlocks[1])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1));
            }

            if (config.DomBlocks[0])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D));
            }
            if (config.DomBlocks[1])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1));
            }

            muA   = config.physParams.mu_A;
            muB   = config.physParams.mu_B;
            rhoA  = config.physParams.rho_A;
            rhoB  = config.physParams.rho_B;
            sigma = config.physParams.Sigma;

            MatInt = !evaporation;

            double kA    = 0.0;
            double kB    = 0.0;
            double hVapA = 0.0;
            double hVapB = 0.0;

            double Tsat  = 0.0;
            double R_int = 0.0;
            double p_c   = 0.0;

            if (evaporation)
            {
                kA    = config.thermParams.k_A;
                kB    = config.thermParams.k_B;
                hVapA = config.thermParams.hVap_A;
                hVapB = config.thermParams.hVap_B;

                Tsat = config.thermParams.T_sat;
                p_c  = config.thermParams.pc;
                //double T_intMin = 0.0;
                double f = config.thermParams.fc;
                double R = config.thermParams.Rc;
                //double pc = config.thermParams.pc;

                if (config.thermParams.hVap_A > 0 && config.thermParams.hVap_B < 0)
                {
                    R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoB * hVapA.Pow2());
                    //T_intMin = Tsat * (1 + (pc / (rhoA * hVapA.Pow2())));
                }
                else if (config.thermParams.hVap_A < 0 && config.thermParams.hVap_B > 0)
                {
                    R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoA * hVapB.Pow2());
                    //T_intMin = Tsat * (1 + (pc / (rhoB * hVapB.Pow2())));
                }
                this.CurvatureRequired = true;
            }



            //if (!MatInt)
            //    throw new NotSupportedException("Non-Material interface is NOT tested!");

            // create Operator
            // ===============
            m_OP = new XSpatialOperator(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree);

            // build the operator
            // ==================
            {
                // Momentum equation
                // =================

                if (config.physParams.IncludeConvection && config.Transport)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var comps = m_OP.EquationComponents[CodName[d]];

                        // convective part:
                        // variante 1:

                        double LFFA = config.dntParams.LFFA;
                        double LFFB = config.dntParams.LFFB;


                        var conv = new Operator.Convection.ConvectionInBulk_LLF(D, BcMap, d, rhoA, rhoB, LFFA, LFFB, LsTrk);
                        comps.Add(conv);                                                                                                                                 // Bulk component

                        comps.Add(new Operator.Convection.ConvectionAtLevelSet_LLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, config.physParams.Material, BcMap, movingmesh)); // LevelSet component
                        //comps.Add(new Operator.Convection.ConvectionAtLevelSet_weightedLLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, BcMap, movingmesh));       // LevelSet component

                        if (evaporation)
                        {
                            //comps.Add(new Operator.Convection.ConvectionAtLevelSet_Divergence(d, D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                            //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterialLLF(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                            //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterial(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                        }

                        // variante 3:
                        //var convA = new LocalConvection(D, d, rhoA, rhoB, this.config.varMode, LsTrk);
                        //XOP.OnIntegratingBulk += convA.SetParameter;
                        //comps.Add(convA);
                        //////var convB = new LocalConvection2(D, d, rhoA, rhoB, varMode, LsTrk); // macht Bum-Bum!
                        ////XOP.OnIntegratingBulk += convB.SetParameter;
                        ////comps.Add(convB);
                    }

                    this.U0meanrequired = true;
                }

                // pressure gradient
                // =================

                if (config.PressureGradient)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var comps = m_OP.EquationComponents[CodName[d]];


                        var pres = new Operator.Pressure.PressureInBulk(d, BcMap);
                        comps.Add(pres);

                        //if (!MatInt)
                        //    throw new NotSupportedException("New Style pressure coupling does not support non-material interface.");
                        var presLs = new Operator.Pressure.PressureFormAtLevelSet(d, D, LsTrk); //, dntParams.UseWeightedAverages, muA, muB);
                        comps.Add(presLs);

                        //if (evaporation) {
                        //    var presLSGen = new Operator.Pressure.GeneralizedPressureFormAtLevelSet(d, D, LsTrk, config.thermParams.p_sat, hVapA);
                        //    comps.Add(presLSGen);
                        //}
                    }
                }

                // viscous operator
                // ================

                if (config.Viscous && !muIs0)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var comps = m_OP.EquationComponents[CodName[d]];
                        // viscous part:
                        //double _D = D;
                        //double penalty_mul = dntParams.PenaltySafety;
                        //double _p = degU;
                        //double penalty_base = (_p + 1) * (_p + _D) / _D;
                        //double penalty = penalty_base * penalty_mul;
                        double penalty = dntParams.PenaltySafety;
                        switch (dntParams.ViscosityMode)
                        {
                        case ViscosityMode.Standard: {
                            // Bulk operator:
                            var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB);         // , _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B);

                            comps.Add(Visc);

                            if (dntParams.UseGhostPenalties)
                            {
                                var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty);
                            }
                            // Level-Set operator:
                            comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, true));

                            break;
                        }

                        case ViscosityMode.TransposeTermMissing: {
                            // Bulk operator:
                            var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB);
                            comps.Add(Visc);

                            if (dntParams.UseGhostPenalties)
                            {
                                var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty);
                            }
                            // Level-Set operator:
                            comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, false));

                            break;
                        }

                        case ViscosityMode.ExplicitTransformation: {
                            // Bulk operator
                            var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB);
                            comps.Add(Visc);
                            if (dntParams.UseGhostPenalties)
                            {
                                var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty);
                            }

                            //Level-Set operator:
                            //comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Explicit(d, D, LsTrk, penalty, muA, muB));
                            throw new NotSupportedException("Beim refact rausgeflogen, braucht eh kein Mensch. fk, 08jan16.");

                            //break;
                        }

                        case ViscosityMode.FullySymmetric: {
                            // Bulk operator
                            var Visc1 = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B);
                            var Visc2 = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm(
                                dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0,
                                BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B);
                            //var Visc3 = new Operator.Viscosity.ViscosityInBulk_divTerm(dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB);


                            comps.Add(Visc1);
                            comps.Add(Visc2);
                            //comps.Add(Visc3);

                            if (dntParams.UseGhostPenalties)
                            {
                                var Visc1Penalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(
                                    penalty, 0.0,
                                    BcMap, d, D, muA, muB);
                                var Visc2Penalty = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm(
                                    penalty, 0.0,
                                    BcMap, d, D, muA, muB);
                                //var Visc3Penalty = new Operator.Viscosity.ViscosityInBulk_divTerm(
                                //    penalty, 0.0,
                                //    BcMap, d, D, muA, muB);
                                //m_OP.OnIntegratingBulk += Visc3Penalty.SetParameter;
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc1Penalty);
                                m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc2Penalty);
                                //m_OP.AndresHint.EquationComponents[CodName[d]].Add(Visc3Penalty);
                            }

                            // Level-Set operator
                            comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, _staticInt, dntParams.UseWeightedAverages));

                            if (this.evaporation)
                            {
                                comps.Add(new Operator.Viscosity.GeneralizedViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                            }

                            break;
                        }

                        default:
                            throw new NotImplementedException();
                        }
                    }
                }

                // Continuum equation
                // ==================

                if (config.continuity)
                {
                    for (int d = 0; d < D; d++)
                    {
                        var src = new Operator.Continuity.DivergenceInBulk_Volume(d, D, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti);
                        var flx = new Operator.Continuity.DivergenceInBulk_Edge(d, BcMap, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti);
                        m_OP.EquationComponents["div"].Add(flx);
                        m_OP.EquationComponents["div"].Add(src);
                    }

                    var divPen = new Operator.Continuity.DivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, MatInt, config.dntParams.ContiSign, config.dntParams.RescaleConti, _staticInt); //, dntParams.UseWeightedAverages, muA, muB);
                    m_OP.EquationComponents["div"].Add(divPen);

                    if (evaporation)
                    {
                        var divPenGen = new Operator.Continuity.GeneralizedDivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c);
                        m_OP.EquationComponents["div"].Add(divPenGen);
                    }

                    //// pressure stabilization
                    //if (this.config.PressureStab) {
                    //    Console.WriteLine("Pressure Stabilization active.");
                    //var pStabi = new PressureStabilization(0.0001, 0.0001);
                    //    m_OP.OnIntegratingBulk += pStabi.SetParameter;
                    //    m_OP.EquationComponents["div"].Add(pStabi);
                    ////var pStabiLS = new PressureStabilizationAtLevelSet(D, LsTrk, rhoA, muA, rhoB, muB, sigma, this.config.varMode, MatInt);
                    //    //XOP.EquationComponents["div"].Add(pStabiLS);
                    //} else {
                    //    Console.WriteLine("Pressure Stabilization INACTIVE.");
                    //}
                }

                // surface tension
                // ===============

                if (config.PressureGradient && config.physParams.Sigma != 0.0)
                {
                    // isotropic part of the surface stress tensor
                    if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux ||
                        config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Local ||
                        config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            if (config.dntParams.SST_isotropicMode != SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine)
                            {
                                IEquationComponent G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5);
                                IEquationComponent H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H);
                            }
                            else
                            {
                                //G = new SurfaceTension_LaplaceBeltrami2_Surface(d, config.physParams.Sigma * 0.5);
                                //H = new SurfaceTension_LaplaceBeltrami2_BndLine(d, config.physParams.Sigma * 0.5, config.physParams.Theta_e, config.physParams.betaL);
                                IEquationComponent isoSurfT = new IsotropicSurfaceTension_LaplaceBeltrami(d, D, config.physParams.Sigma * 0.5, BcMap.EdgeTag2Type, BcMap, config.physParams.theta_e, config.physParams.betaL, _staticInt);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(isoSurfT);
                            }
                        }

                        this.NormalsRequired = true;
                    }
                    else if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Projected ||
                             config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_ClosestPoint ||
                             config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_LaplaceBeltramiMean ||
                             config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            m_OP.EquationComponents[CodName[d]].Add(new CurvatureBasedSurfaceTension(d, D, LsTrk, config.physParams.Sigma));
                        }

                        this.CurvatureRequired = true;

                        /*
                         * Console.WriteLine("REM: hack in Operator factory");
                         * for(int d = 0; d < D; d++) {
                         *  //var G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5);
                         *  var H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.surfTensionMode == SurfaceTensionMode.LaplaceBeltrami_Flux);
                         *
                         *  //m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G);
                         *  m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H);
                         * }
                         *
                         * this.NormalsRequired = true;
                         */
                    }
                    else
                    {
                        throw new NotImplementedException("Not implemented.");
                    }


                    // dynamic part
                    if (config.dntParams.SurfStressTensor != SurfaceSressTensor.Isotropic)
                    {
                        double muI  = config.physParams.mu_I;
                        double lamI = config.physParams.lambda_I;

                        double penalty_base = (degU + 1) * (degU + D) / D;
                        double penalty      = penalty_base * dntParams.PenaltySafety;

                        // surface shear viscosity
                        if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceRateOfDeformation ||
                            config.dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit ||
                            config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven)
                        {
                            for (int d = 0; d < D; d++)
                            {
                                var surfDeformRate = new BoussinesqScriven_SurfaceDeformationRate_GradU(d, muI * 0.5, penalty);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRate);
                                //m_OP.OnIntegratingSurfaceElement += surfDeformRate.SetParameter;

                                if (config.dntParams.SurfStressTensor != SurfaceSressTensor.SemiImplicit)
                                {
                                    var surfDeformRateT = new BoussinesqScriven_SurfaceDeformationRate_GradUTranspose(d, muI * 0.5, penalty);
                                    m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRateT);
                                    //m_OP.OnIntegratingSurfaceElement += surfDeformRateT.SetParameter;
                                }
                            }
                        }
                        // surface dilatational viscosity
                        if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceVelocityDivergence ||
                            config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven)
                        {
                            for (int d = 0; d < D; d++)
                            {
                                var surfVelocDiv = new BoussinesqScriven_SurfaceVelocityDivergence(d, muI * 0.5, lamI * 0.5, penalty, BcMap.EdgeTag2Type);
                                m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfVelocDiv);
                                //m_OP.OnIntegratingSurfaceElement += surfVelocDiv.SetParameter;
                            }
                        }
                    }


                    // stabilization
                    if (config.dntParams.UseLevelSetStabilization)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            m_OP.EquationComponents[CodName[d]].Add(new LevelSetStabilization(d, D, LsTrk));
                        }
                    }
                }


                // surface force term
                // ==================


                if (config.PressureGradient && config.physParams.useArtificialSurfaceForce)
                {
                    for (int d = 0; d < D; d++)
                    {
                        m_OP.EquationComponents[CodName[d]].Add(new SurfaceTension_ArfForceSrc(d, D, LsTrk));
                    }
                }


                // evaporation (mass flux)
                // =======================

                if (evaporation)
                {
                    for (int d = 0; d < D; d++)
                    {
                        m_OP.EquationComponents[CodName[d]].Add(new Operator.DynamicInterfaceConditions.MassFluxAtInterface(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c));
                    }
                }
            }

            // Finalize
            // ========

            m_OP.Commit();
        }