Ejemplo n.º 1
0
        /// <summary>
        /// Specifies the control object for application startup; overrides any startup arguments (<see cref="CommandLineArguments"/>)
        /// set so far.
        /// </summary>
        public void SetControlObject(BoSSS.Solution.Control.AppControl ctrl)
        {
            TestActivation();

            // serialize control object
            // ========================

            // grid function hack:
            if (ctrl.GridFunc != null)
            {
                Console.WriteLine("Control object contains grid function. Trying to Serialize the grid...");
                var dbi = ctrl.GetDatabase();
                if (dbi == null)
                {
                    throw new NotSupportedException("If a gird function is specified (instead of a grid id), a database must be specified to save the gird (when using the job manager).");
                }

                Foundation.Grid.IGrid g = ctrl.GridFunc();
                Guid id = dbi.SaveGrid(ref g);

                ctrl.GridFunc = null;
                ctrl.GridGuid = id;
                Console.WriteLine("Control object modified.");
            }


            ctrl.VerifyEx();
            m_ctrl             = ctrl;
            m_ctrl.ProjectName = InteractiveShell.WorkflowMgm.CurrentProject;

            // note: serialization is done later, immediately before deployment,
            // since we may need to fix database issues (path on batch system, evtl. transfer of grid)

            m_ctrl_index = -1;
            if (m_ctrl.GeneratedFromCode)
            {
                ControlName  = "control.cs";
                m_ctrl_index = m_ctrl.ControlFileText_Index;
            }
            else
            {
                ControlName = "control.obj";
            }


            // Project & Session Name
            // ======================
            string PrjName = InteractiveShell.WorkflowMgm.CurrentProject;

            if (string.IsNullOrWhiteSpace(PrjName))
            {
                throw new NotSupportedException("Project management not initialized - set project name (try e.g. 'WorkflowMgm.CurrentProject = \"BlaBla\"').");
            }

            string[] args = new string[] {
                "--control", "control.obj",
                "--prjnmn", PrjName,
                "--sesnmn", this.Name
            };
            if (m_ctrl_index >= 0)
            {
                ArrayTools.Cat(args, "--pstudy_case", m_ctrl_index.ToString());
            }

            m_EnvironmentVars.Clear();
            for (int i = 0; i < args.Length; i++)
            {
                m_EnvironmentVars.Add("BOSSS_ARG_" + i, args[i]);
            }

            //
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Based on the Ideas by
        /// C. Basting and D. Kuzmin,
        /// “A minimization-based finite element formulation for interface-preserving level set reinitialization”,
        /// Computing, vol. 95, no. 1, pp. 13–25, Dec. 2012.
        /// Create Spatial Operators and build the corresponding Matrices
        /// For the Left-Hand Side of the ReInitProblem
        /// RHS is computed on the fly in <see cref="ReInitSingleStep"/>
        /// The Bulk component is constant unless the grid changes, thus it is computed in <see cref="BuildOperators(CellQuadratureScheme)"/>.
        /// The Interface component changes with its motion.
        /// This component is calculated in <see cref="UpdateOperators(CellQuadratureScheme)"/>.
        /// </summary>
        /// <param name="LSTrck"></param>
        /// <param name="Control">various parameters <paramref name="EllipticReinitControl"/></param>
        /// <param name="HMFOrder">order of tghe interface quadrature</param>
        public EllipticReInit(LevelSetTracker LSTrck, EllipticReInitAlgoControl Control, SinglePhaseField LevelSetForReInit = null)
        {
            this.Control         = Control;
            this.LevelSetTracker = LSTrck;
            if (LevelSetForReInit == null)
            {
                Phi = LevelSetTracker.LevelSets[0] as SinglePhaseField;
            }
            else
            {
                Phi = LevelSetForReInit;
            }
            this.underrelaxation = Control.underrelaxation;

            Residual = new SinglePhaseField(Phi.Basis);
            OldPhi   = new SinglePhaseField(Phi.Basis);
            NewPhi   = new SinglePhaseField(Phi.Basis);
            foreach (SinglePhaseField f in new List <SinglePhaseField> {
                Residual, OldPhi, NewPhi
            })
            {
                f.Clear();
                f.Acc(1.0, Phi);
            }


            this.D = LevelSetTracker.GridDat.SpatialDimension;

            this.ConvergenceCriterion = Control.ConvergenceCriterion;
            this.MaxIteration         = Control.MaxIt;

            double PenaltyBase = ((double)((Phi.Basis.Degree + 1) * (Phi.Basis.Degree + D))) / ((double)D);


            // Choose Forms according to Upwinding or Central Fluxes
            string[] paramNames;
            int      noOfParamFields;

            IEquationComponent BulkForm;
            RHSForm            myRHSForm;

            LevelSetGradient     = new VectorField <SinglePhaseField>(D, Phi.Basis, "LevelSetGradient", SinglePhaseField.Factory);
            MeanLevelSetGradient = new VectorField <SinglePhaseField>(D, new Basis(Phi.GridDat, 0), "MeanLevelSetGradient", SinglePhaseField.Factory);

            if (Control.Upwinding)
            {
                paramNames      = new string[] { "OldLevelSet", "MeanLevelSetGradient[0]", "MeanLevelSetGradient[1]" };
                noOfParamFields = D;
                LevelSetGradient.Clear();
                LevelSetGradient.Gradient(1.0, Phi);
                //LevelSetGradient.GradientByFlux(1.0, Phi);
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);

                parameterFields = ArrayTools.Cat(new SinglePhaseField[] { OldPhi }, MeanLevelSetGradient.ToArray());
                //throw new NotImplementedException("ToDO");
                BulkForm  = new EllipticReInitUpwindForm_Laplace(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);
                myRHSForm = new EllipticReInitUpwindForm_RHS(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);

                OldDirection = new double[MeanLevelSetGradient.CoordinateVector.ToArray().Length];
                for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++)
                {
                    OldDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]);
                }
                NewDirection = OldDirection.CloneAs();
            }
            else
            {
                paramNames      = new string[] { };
                noOfParamFields = 0;
                parameterFields = new SinglePhaseField[] { };
                BulkForm        = new CentralDifferencesLHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck.GridDat.Cells.cj);
                myRHSForm       = new CentralDifferencesRHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);
            }


            // SIP for the bulk Phase
            //this.Operator_bulk = new SpatialOperator(1, noOfParamFields, 1, QuadOrderFunc.SumOfMaxDegrees(1, RoundUp: false), variableNames);
            this.Operator_bulk = BulkForm.Operator();



            // Zero at the Interface
            // Calculate Quadrature Order
            Func <int[], int[], int[], int> InterfaceQuadOrder;

            InterfaceQuadOrder = QuadOrderFunc.FixedOrder(Phi.Basis.Degree * 2 + 2);

            // Generate Interface Operator
            this.Operator_interface = (new EllipticReInitInterfaceForm(Control.PenaltyMultiplierInterface * PenaltyBase, LSTrck)).XOperator(new[] { "A" }, InterfaceQuadOrder);

            // Nonlinear Part on the RHS
            // switch for the potential functions
            switch (Control.Potential)
            {
            case ReInitPotential.BastingDoubleWell: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWell(d, b));
                break;
            };

            case ReInitPotential.BastingSingleWell: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWell(d, b));
                break;
            };

            case ReInitPotential.SingleWellNear: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellNear(d, b));
                break;
            };

            case ReInitPotential.P4DoubleWell: {
                Console.WriteLine("Warning - This Option for Elliptic ReInit does not work well");
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWellAlternative(d, b));
                break;
            };

            case ReInitPotential.SingleWellOnCutDoubleWellElse: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellOnCutDoubleWellElse(d, b));
                break;
            }
            }
            Operator_RHS = myRHSForm.Operator(QuadOrderFunc.SumOfMaxDegrees(2, RoundUp: true));


            // The result of the nonlinear part on the rhs is projected on a single-phase field
            RHSField = new SinglePhaseField(Phi.Basis, "RHS");

            OpMatrix = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine = new double[OpMatrix.RowPartitioning.LocalLength];

            // Matrix and RHS for the Bulk component
            OpMatrix_bulk = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength];

            // Matrix and RHS for the Interface Penalty
            OpMatrix_interface = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength];

            // Init Parameter Fields
            OldPhi.Clear();
            OldPhi.Acc(1.0, Phi);

            // Compute Matrices
            UpdateBulkMatrix();
        }
Ejemplo n.º 3
0
        static void InfoRecursive(object obj, int RecursionDepth, int MaxRecursionDepth)
        {
            if (obj == null)
            {
                Console.WriteLine("Null");
                return;
            }

            if (RecursionDepth > MaxRecursionDepth)
            {
                Console.WriteLine(" ... no further recursion - max recursion depth reached.");
                return;
            }

            Type objT = obj.GetType();

            if ((objT.IsPrimitive || objT.IsEnum || objT == typeof(string)))
            {
                Console.WriteLine(obj.ToString() + " (" + objT.Name + ")");
                return;
            }

            if (objT.IsSubclassOf(typeof(System.Delegate)))
            {
                // unable to log delegates
                Console.WriteLine("Delegate");
                return;
            }

            void WriteSpaces()
            {
                //Console.WriteLine();
                for (int i = 0; i < RecursionDepth; i++)
                {
                    Console.Write(" ");
                }
            }

            if (obj is System.Collections.IEnumerable)
            {
                System.Collections.IEnumerable objEnu = (System.Collections.IEnumerable)obj;
                int cnt = 0;
                foreach (var objE in objEnu)
                {
                    WriteSpaces();
                    Console.Write("[{0}]: ", cnt);
                    cnt++;
                    InfoRecursive(objE, RecursionDepth + 1, MaxRecursionDepth);
                }
                return;
            }

            BindingFlags biFlags = BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty;

            MemberInfo[] PIs = objT.GetProperties(biFlags);
            MemberInfo[] FIs = objT.GetFields(biFlags);

            foreach (MemberInfo mi in ArrayTools.Cat(PIs, FIs))
            {
                WriteSpaces();
                Console.Write(mi.Name + ": ");

                object Val;
                if (mi is PropertyInfo)
                {
                    PropertyInfo pi = ((PropertyInfo)mi);
                    if (!pi.CanRead)
                    {
                        Console.WriteLine("cannot read.");
                        continue;
                    }
                    if (pi.GetIndexParameters() != null && pi.GetIndexParameters().Length > 0)
                    {
                        // no support for indexed properties.
                        Console.WriteLine("indexed property - not supported.");
                        continue;
                    }

                    //pi.GetIndexParameters
                    try {
                        Val = pi.GetValue(obj, biFlags, null, null, null);
                    } catch (TargetInvocationException tie) {
                        Console.WriteLine(tie.GetType().Name + ": " + tie.Message);
                        continue;
                    }
                }
                else if (mi is FieldInfo)
                {
                    Val = ((FieldInfo)mi).GetValue(obj);
                }
                else
                {
                    Console.WriteLine("unsupported member type: " + mi.GetType().FullName + ".");
                    continue;
                }

                InfoRecursive(Val, RecursionDepth + 1, MaxRecursionDepth);
            }
        }
Ejemplo n.º 4
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();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// ctor for the operator factory, where the equation compnents are set
        /// </summary>
        /// <param name="config"></param>
        /// <param name="_LsTrk"></param>
        /// <param name="_HMFdegree"></param>
        /// <param name="BcMap"></param>
        /// <param name="degU"></param>
        public XNSE_OperatorFactory(IXNSE_Configuration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int degU)
        {
            this.LsTrk = _LsTrk;
            this.D     = _LsTrk.GridDat.SpatialDimension;

            this.HMFDegree = _HMFdegree;

            this.physParams = config.getPhysParams;
            this.dntParams  = config.getDntParams;


            // test input
            // ==========
            {
                if (config.getDomBlocks.GetLength(0) != 2 || config.getCodBlocks.GetLength(0) != 2)
                {
                    throw new ArgumentException();
                }

                if ((config.getPhysParams.mu_A <= 0) && (config.getPhysParams.mu_B <= 0))
                {
                    config.isViscous = false;
                }
                else
                {
                    if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0))
                    {
                        throw new ArgumentException();
                    }
                }

                if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.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 = ArrayTools.Cat(EquationNames.MomentumEquations(D), EquationNames.ContinuityEquation);
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(D),
                VariableNames.Velocity0MeanVector(D),
                VariableNames.NormalVector(D),
                VariableNames.Curvature,
                VariableNames.SurfaceForceVector(D)
                );
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure);

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

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


            // create Operator
            // ===============
            m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray());

            // add components
            // ==============

            // species bulk components
            for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++)
            {
                // Navier Stokes equations
                XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired);

                // continuity equation
                if (config.isContinuity)
                {
                    XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap);
                }
            }

            // interface components
            XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk);                                                          // surface stress tensor
            XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force

            if (config.isContinuity)
            {
                XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk);       // continuity equation
            }
            m_XOp.Commit();
        }
Ejemplo n.º 6
0
        /// <summary>
        /// ctor for the operator factory, where the equation compnents are set
        /// </summary>
        /// <param name="_config"></param>
        /// <param name="_LsTrk"></param>
        /// <param name="_HMFdegree"></param>
        /// <param name="BcMap"></param>
        /// <param name="thermBcMap"></param>
        /// <param name="degU"></param>
        public XNSFE_OperatorFactory(XNSFE_OperatorConfiguration _config, LevelSetTracker _LsTrk, int _HMFdegree,
                                     IncompressibleMultiphaseBoundaryCondMap BcMap, ThermalMultiphaseBoundaryCondMap thermBcMap, int degU, IDictionary <SpeciesId, IEnumerable <double> > MassScale)
        {
            this.config = _config;
            this.LsTrk  = _LsTrk;
            this.D      = _LsTrk.GridDat.SpatialDimension;

            this.HMFDegree = _HMFdegree;

            this.physParams  = config.getPhysParams;
            this.thermParams = config.getThermParams;
            this.dntParams   = config.getDntParams;


            // test input
            // ==========
            {
                if ((config.getPhysParams.mu_A <= 0) && (config.getPhysParams.mu_B <= 0))
                {
                    config.isViscous = false;
                }
                else
                {
                    if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0))
                    {
                        throw new ArgumentException();
                    }
                }

                if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.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 = ArrayTools.Cat(EquationNames.MomentumEquations(D), EquationNames.ContinuityEquation);
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(D),
                VariableNames.Velocity0MeanVector(D),
                VariableNames.NormalVector(D),
                VariableNames.Curvature,
                VariableNames.SurfaceForceVector(D)
                );
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure);

            if (config.solveEnergy)
            {
                CodName = ArrayTools.Cat(CodName, EquationNames.KineticEnergyEquation);
                Params  = ArrayTools.Cat(Params,
                                         VariableNames.VelocityX_GradientVector(),
                                         VariableNames.VelocityY_GradientVector(),
                                         new string[] { "VelocityXGradX_GradientX", "VelocityXGradX_GradientY" },
                                         new string[] { "VelocityXGradY_GradientX", "VelocityXGradY_GradientY" },
                                         new string[] { "VelocityYGradX_GradientX", "VelocityYGradX_GradientY" },
                                         new string[] { "VelocityYGradY_GradientX", "VelocityYGradY_GradientY" },
                                         VariableNames.Pressure0,
                                         VariableNames.PressureGradient(D),
                                         VariableNames.GravityVector(D)
                                         );
                DomName = ArrayTools.Cat(DomName, VariableNames.KineticEnergy);
            }

            if (config.solveHeat)
            {
                Params = ArrayTools.Cat(Params,
                                        VariableNames.Temperature0,
                                        VariableNames.HeatFlux0Vector(D),
                                        VariableNames.DisjoiningPressure
                                        );
                if (config.conductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP)
                {
                    CodName = ArrayTools.Cat(CodName, EquationNames.HeatEquation);
                    DomName = ArrayTools.Cat(DomName, VariableNames.Temperature);
                }
                else
                {
                    CodName = ArrayTools.Cat(CodName, EquationNames.HeatEquation, EquationNames.AuxHeatFlux(D));
                    DomName = ArrayTools.Cat(DomName, VariableNames.Temperature, VariableNames.HeatFluxVector(D));
                }
            }

            storedParams = new DGField[Params.Length];

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

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

            int nBlocks = 2;

            if (config.solveEnergy)
            {
                nBlocks = 3;
                if (config.getCodBlocks[2])
                {
                    CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D + 1, 1));
                }
                if (config.getDomBlocks[2])
                {
                    DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D + 1, 1));
                }
            }

            if (config.solveHeat)
            {
                if (config.getCodBlocks[nBlocks])
                {
                    CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(nBlocks + (D - 1) + 1, 1));
                }
                if (config.getDomBlocks[nBlocks])
                {
                    DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(nBlocks + (D - 1) + 1, 1));
                }

                if (config.conductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP)
                {
                    if (config.getCodBlocks[nBlocks + 1])
                    {
                        CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(nBlocks + (D - 1) + 2, D));
                    }
                    if (config.getDomBlocks[nBlocks + 1])
                    {
                        DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(nBlocks + (D - 1) + 2, D));
                    }
                }
            }


            // create Operator
            // ===============
            m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesNames);

            // add Navier-Stokes components
            // ============================

            // species bulk components
            for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++)
            {
                // Navier Stokes equations
                Solution.XNSECommon.XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired);

                // continuity equation
                if (config.isContinuity)
                {
                    Solution.XNSECommon.XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap);
                }
            }

            // interface components
            Solution.XNSECommon.XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk);                                                          // surface stress tensor
            Solution.XNSECommon.XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force

            if (config.isContinuity)
            {
                Solution.XNSECommon.XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk);       // continuity equation
            }
            // add kinetic energy equation components
            // ======================================
            if (config.solveEnergy)
            {
                // species bulk components
                for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++)
                {
                    Solution.EnergyCommon.XOperatorComponentsFactory.AddSpeciesKineticEnergyEquation(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk);
                }

                // interface components
                Solution.EnergyCommon.XOperatorComponentsFactory.AddInterfaceKineticEnergyEquation(m_XOp, config, D, BcMap, LsTrk, degU);
                CurvatureRequired = true;
            }


            // add Heat equation components
            // ============================
            if (config.solveHeat)
            {
                // species bulk components
                for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++)
                {
                    Solution.XheatCommon.XOperatorComponentsFactory.AddSpeciesHeatEq(m_XOp, config,
                                                                                     D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], thermBcMap, LsTrk);
                }

                // interface components
                Solution.XheatCommon.XOperatorComponentsFactory.AddInterfaceHeatEq(m_XOp, config, D, thermBcMap, LsTrk);
            }


            // add Evaporation interface components
            // ====================================

            if (config.isEvaporation)
            {
                XOperatorComponentsFactory.AddInterfaceNSE_withEvaporation(m_XOp, config, D, LsTrk);
                if (config.isContinuity)
                {
                    XOperatorComponentsFactory.AddInterfaceContinuityEq_withEvaporation(m_XOp, config, D, LsTrk);
                }
            }

            // create temporal operator
            // ========================
            var TempOp = new ConstantXTemporalOperator(m_XOp, 0.0);

            m_XOp.TemporalOperator = TempOp;
            foreach (var kv in MassScale)
            {
                TempOp.DiagonalScale[LsTrk.GetSpeciesName(kv.Key)].SetV(kv.Value.ToArray());
            }

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

            m_XOp.Commit();
        }
Ejemplo n.º 7
0
        public ExtensionVelocityBDFMover(LevelSetTracker LSTrk,
                                         SinglePhaseField LevelSet,
                                         VectorField <SinglePhaseField> LevelSetGradient,
                                         VectorField <DGField> Velocity,
                                         EllipticExtVelAlgoControl Control,
                                         IncompressibleBoundaryCondMap bcMap,
                                         int BDForder,
                                         VectorField <SinglePhaseField> VectorExtension,
                                         double[] Density = null,
                                         bool AssumeDivergenceFreeVelocity = false, SubGrid subGrid = null)
        {
            this.GridDat          = LSTrk.GridDat;
            D                     = GridDat.SpatialDimension;
            this.LevelSetGradient = LevelSetGradient;
            this.LSTrk            = LSTrk;
            this.LevelSet         = LevelSet;

            this.Velocity = Velocity;
            this.OldRHS   = LevelSet.CloneAs();
            this.AdvectionSpatialOperator = CreateAdvectionSpatialOperator(bcMap);

            this.subGrid   = subGrid;
            this.nearfield = subGrid != null;

            Basis NonXVelocityBasis;

            if (Velocity == null)
            {
                throw new ArgumentException("Velocity Field not initialized!");
            }

            // Initialize Extension Velocity Algorithm
            double        PenaltyBase = Control.PenaltyMultiplierInterface * ((double)((LevelSet.Basis.Degree + 1) * (LevelSet.Basis.Degree + D))) / ((double)D);
            ILevelSetForm InterfaceFlux;



            //VectorExtension = new VectorField<SinglePhaseField>(D, Velocity[0].Basis, "ExtVel", SinglePhaseField.Factory);
            if (Velocity[0].GetType() == typeof(SinglePhaseField))
            {
                NonXVelocityBasis = ((SinglePhaseField)Velocity[0]).Basis;
                InterfaceFlux     = new SingleComponentInterfaceForm(PenaltyBase, LSTrk);
            }
            else if (Velocity[0].GetType() == typeof(XDGField))
            {
                NonXVelocityBasis = ((XDGField)Velocity[0]).Basis.NonX_Basis;
                InterfaceFlux     = new DensityWeightedExtVel(PenaltyBase, LSTrk, Density);
            }
            else
            {
                throw new ArgumentException("VelocityField must be either a SinglePhaseField or a XDGField!");
            };
            //VectorExtension = new VectorField<SinglePhaseField>(D, NonXVelocityBasis, "ExtVel", SinglePhaseField.Factory);
            this.VectorExtension = VectorExtension;



            VelocityExtender = new Extender[D];
            for (int d = 0; d < D; d++)
            {
                VelocityExtender[d] = new Extender(VectorExtension[d], LSTrk, InterfaceFlux, new List <DGField> {
                    Velocity[d]
                }, LevelSetGradient, Control);
                VelocityExtender[d].ConstructExtension(new List <DGField> {
                    Velocity[d]
                }, Control.subGridRestriction);
            }
#if DEBUG
            VectorExtension.CheckForNanOrInf();
#endif

            // Initialize Advection Algorithm
            divU = new SinglePhaseField(NonXVelocityBasis);
            divU.Identification = "Divergence";
            divU.Clear();
            divU.Divergence(1.0, VectorExtension);
            MeanVelocity = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(new Basis(GridDat, 0), VariableNames.Velocity0MeanVector(D)[d])));
            MeanVelocity.Clear();
            MeanVelocity.AccLaidBack(1.0, VectorExtension);
            myBDFTimestepper = new BDFTimestepper(AdvectionSpatialOperator, new List <DGField>()
            {
                LevelSet
            }, ArrayTools.Cat(VectorExtension, this.MeanVelocity, this.divU), BDForder, Control.solverFactory, false, subGrid);
        }
Ejemplo n.º 8
0
        public void Init(MultigridOperator op)
        {
            int D = op.GridData.SpatialDimension;

            CodName = (new string[] { "mom0", "mom1" });
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(D));
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(D));

            LocalOp = new SpatialOperator(DomName, Params, CodName, (A, B, C) => 4);

            for (int d = 0; d < D; d++)
            {
                LocalOp.EquationComponents["mom" + d].Add(new LocalDiffusiveFlux()
                {
                    m_component = d, dt = m_dt, muA = m_muA
                });
            }

            LocalOp.Commit();

            //LocalMatrix = op.MassMatrix.CloneAs().ToMsrMatrix();
            //LocalMatrix.Clear();

            //var U0 = new VectorField<SinglePhaseField>(op.BaseGridProblemMapping Take(D).Select(F => (SinglePhaseField)F).ToArray());

            UnsetteledCoordinateMapping test = new UnsetteledCoordinateMapping(op.BaseGridProblemMapping.BasisS.GetSubVector(0, D));

            var U0 = ((BoSSS.Foundation.CoordinateMapping)op.Mapping.ProblemMapping).Fields.GetSubVector(0, 2);

            var empty = new SinglePhaseField[D];

            LocalMatrix = LocalOp.ComputeMatrix(test, empty, test, time: m_dt);


            Uidx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, D.ForLoop(i => i));
            Pidx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, D);

            int Upart = Uidx.Length;
            int Ppart = Pidx.Length;

            ConvDiff = null;                           // new BlockMsrMatrix(Upart, Upart, 1, 1);
            pGrad    = null;                           // new BlockMsrMatrix(Upart, Ppart, 1, 1);
            divVel   = null;                           // new BlockMsrMatrix(Ppart, Upart, 1, 1);
            BlockMsrMatrix VelocityMass        = null; // new BlockMsrMatrix(Upart, Upart, 1, 1);
            BlockMsrMatrix leftChangeBasesVel  = null; // new BlockMsrMatrix(Upart, Upart, 1, 1);
            BlockMsrMatrix rightChangeBasesVel = null; // new BlockMsrMatrix(Upart, Upart, 1, 1);

            op.MassMatrix.AccSubMatrixTo(1.0, VelocityMass, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));

            op.LeftChangeOfBasis.AccSubMatrixTo(1.0, leftChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));
            op.RightChangeOfBasis.AccSubMatrixTo(1.0, rightChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));

            var temp = BlockMsrMatrix.Multiply(leftChangeBasesVel, LocalMatrix);

            LocalMatrix = BlockMsrMatrix.Multiply(temp, rightChangeBasesVel);

            var M = op.OperatorMatrix;

            M.AccSubMatrixTo(1.0, ConvDiff, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));
            M.AccSubMatrixTo(1.0, pGrad, Uidx, default(int[]), Pidx, default(int[]), default(int[]), default(int[]));
            M.AccSubMatrixTo(1.0, divVel, Pidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[]));

            //LocalMatrix.SaveToTextFileSparse("LocalConvDiffMatrix");
            //ConvDiff.SaveToTextFileSparse("ConvDiff");
            //op.MassMatrix.SaveToTextFileSparse("MassMatrix");
            //VelocityMass.SaveToTextFileSparse("VelocityMass");
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Ctor.
 /// </summary>
 /// <param name="LevelSetMapping"></param>
 /// <param name="Velocity0"></param>
 /// <param name="Velocity0Mean"></param>
 /// <param name="SolverConf"></param>
 public LevelSetAdvectionOperator(UnsetteledCoordinateMapping LevelSetMapping,
                                  VectorField <SinglePhaseField> Velocity0, VectorField <SinglePhaseField> Velocity0Mean, SolverConfiguration SolverConf)
     : base(LevelSetMapping, LevelSetMapping, ArrayTools.Cat <SinglePhaseField>(Velocity0.ToArray(), Velocity0Mean.ToArray()),
            SolverConf, IsConstant: false)
 {
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Create Spatial Operators and build the corresponding Matrices
        /// </summary>
        public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield)
        {
            OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength];


            //LevelSetTracker.GetLevelSetGradients(0,);

            // bulk part of the matrix
            //Operator_bulk.ComputeMatrix(
            //    Extension.Mapping,
            //    LevelSetGradient.ToArray(),
            //    Extension.Mapping,
            //    OpMatrix_bulk, OpAffine_bulk,
            //    OnlyAffine: false, sgrd: null);

            switch (Control.FluxVariant)
            {
            case FluxVariant.GradientBased:
                // Flux Direction based on Mean Level Set Gradient
                BulkParams = new List <DGField> {
                };                                      // Hack, to make ArrayTools.Cat produce a List of DGFields
                // second Hack: Does only work, when InterfaceParams is according to a single component flux,
                // else, we will have to change the boundary edge flux
                BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray());
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);
                break;

            case FluxVariant.ValueBased:
                // Flux Direction Based on Cell-Averaged Level-Set Value
                BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet);
                MeanLevelSet.Clear();
                MeanLevelSet.AccLaidBack(1.0, Phi);
                break;

            case FluxVariant.SWIP:
                BulkParams = LevelSetGradient.ToArray();
                break;

            default:
                throw new Exception();
            }

            // Build Operator

            Operator_bulk.ComputeMatrixEx(Extension.Mapping,
                                          BulkParams,
                                          Extension.Mapping,
                                          OpMatrix_bulk, OpAffine_bulk,
                                          OnlyAffine: false,
                                          time: 0.0,
                                          edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null),
                                          volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null)
                                          );



            //Operator_interface.ComputeMatrixEx(
            //    LevelSetTracker,
            //    Extension.Mapping,
            //    InterfaceParams,
            //    Extension.Mapping,
            //    OpMatrix_interface,
            //    OpAffine_interface,
            //    OnlyAffine: false,
            //    time: 0,
            //    MPIParameterExchange: false,
            //    whichSpc: LevelSetTracker.GetSpeciesId("A")
            //    );

            Operator_interface.OperatorCoefficientsProvider =
                delegate(LevelSetTracker lstrk, SpeciesId spc, int quadOrder, int TrackerHistoryIdx, double time) {
                var r = new CoefficientSet()
                {
                };

                //throw new NotImplementedException("todo");
                return(r);
            };
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker,
                                                                                                  Extension.Mapping, InterfaceParams, Extension.Mapping);

            MultiphaseCellAgglomerator dummy = LevelSetTracker.GetAgglomerator(LevelSetTracker.SpeciesIdS.ToArray(), 2 * Extension.Basis.Degree + 2, 0.0);

            mtxBuilder.CellLengthScales.Add(LevelSetTracker.GetSpeciesId("A"), dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]);

            mtxBuilder.time           = 0;
            mtxBuilder.MPITtransceive = false;
            mtxBuilder.ComputeMatrix(OpMatrix_interface, OpAffine_interface);

#if DEBUG
            OpMatrix_bulk.CheckForNanOrInfM();
            OpAffine_bulk.CheckForNanOrInfV();

            OpMatrix_interface.CheckForNanOrInfM();
            OpAffine_interface.CheckForNanOrInfV();
#endif

            //Only for Debugging purposes

            Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0");
            Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0");
#if DEBUG
            //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() );
#endif
            OpMatrix.Clear();
            OpMatrix.Acc(1.0, OpMatrix_bulk);
            OpMatrix.Acc(1.0, OpMatrix_interface);
            //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation());
            OpMatrix.AssumeSymmetric = false;

            OpAffine.Clear();
            OpAffine.AccV(1.0, OpAffine_bulk);
            OpAffine.AccV(1.0, OpAffine_interface);
#if DEBUG
            //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest());
#endif
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="SpatDim">Spatial dimension (either 2 or 3)</param>
        /// <param name="NumberOfReactants"></param>
        /// <param name="BcMap"></param>
        /// <param name="EoS">Null for multiphase. Has to be given for Low-Mach and combustion to calculate density.</param>
        /// <param name="idx">Index of scalar in array, </param>
        /// <param name="Argument">Variable name of the argument (e.g. "Temperature" or "MassFraction0")</param>
        public LinearizedScalarConvection2Jacobi(int SpatDim, int NumberOfReactants, IncompressibleBoundaryCondMap BcMap, MaterialLaw EoS, int idx)
        {
            this.NumberOfReactants = NumberOfReactants;
            m_SpatialDimension     = SpatDim;
            m_bcmap       = BcMap;
            argumentIndex = m_SpatialDimension + idx;

            velFunction = new Func <double[], double, double> [GridCommons.FIRST_PERIODIC_BC_TAG, SpatDim];

            for (int d = 0; d < SpatDim; d++)
            {
                velFunction.SetColumn(m_bcmap.bndFunction[VariableNames.Velocity_d(d)], d);
            }


            switch (BcMap.PhysMode)
            {
            case PhysicsMode.Multiphase:
                //this.Argument = VariableNames.LevelSet;
                m_ArgumentOrdering = new string[] { VariableNames.LevelSet };
                break;

            case PhysicsMode.LowMach:

                m_ArgumentOrdering = ArrayTools.Cat(VariableNames.VelocityVector(SpatDim), VariableNames.Temperature);     // VelocityX,VelocityY,(VelocityZ), Temperature as variables.

                if (EoS == null)
                {
                    throw new ApplicationException("EoS has to be given for Low-Mach flows to calculate density.");
                }
                else
                {
                    this.EoS = EoS;
                }
                break;

            case PhysicsMode.MixtureFraction:
                ;
                m_ArgumentOrdering = ArrayTools.Cat(VariableNames.VelocityVector(SpatDim), VariableNames.MixtureFraction);     // VelocityX,VelocityY,(VelocityZ), MixtureFraction as variables.

                if (EoS == null)
                {
                    throw new ApplicationException("EoS has to be given for Low-Mach flows to calculate density.");
                }
                else
                {
                    this.EoS = EoS;
                }
                break;

            case PhysicsMode.Combustion:
                m_ArgumentOrdering = ArrayTools.Cat(VariableNames.VelocityVector(SpatDim), VariableNames.Temperature, VariableNames.MassFractions(NumberOfReactants - 1));     // u,v,w,T, Y0,Y1,Y2,Y3  as variables (Y4 is calculated as Y4 = 1- (Y0+Y1+Y2+Y3)
                if (EoS == null)
                {
                    throw new ApplicationException("EoS has to be given for Low-Mach flows to calculate density.");
                }
                else
                {
                    this.EoS = EoS;
                }
                break;

            default:
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// ctor.
        /// </summary>
        internal NECQuadratureLevelSet(IGridData context,
                                       XSpatialOperatorMk2 DiffOp,
                                       V __ResultVector,
                                       IList <DGField> __DomainFields,
                                       IList <DGField> __Parameters,
                                       UnsetteledCoordinateMapping CodomainMap,
                                       LevelSetTracker lsTrk, int _iLevSet, Tuple <SpeciesId, SpeciesId> SpeciesPair,
                                       ICompositeQuadRule <QuadRule> domAndRule) //
            : base(new int[] { CodomainMap.MaxTotalNoOfCoordinatesPerCell },
                   context,
                   domAndRule) //
        {
            // -----------------------------------
            // set members / check ctor parameters
            // -----------------------------------
            m_lsTrk            = lsTrk;
            this.m_LevSetIdx   = _iLevSet;
            this.m_SpeciesPair = SpeciesPair;
            this.ResultVector  = __ResultVector;
            m_CodomainMap      = CodomainMap;
            var _Parameters = (__Parameters != null) ? __Parameters.ToArray() : new DGField[0];

            if (__DomainFields.Count != DiffOp.DomainVar.Count)
            {
                throw new ArgumentException("mismatch between number of domain variables in spatial operator and given domain variables");
            }
            if (_Parameters.Length != DiffOp.ParameterVar.Count)
            {
                throw new ArgumentException("mismatch between number of parameter variables in spatial operator and given parameters");
            }
            if (m_CodomainMap.NoOfVariables != DiffOp.CodomainVar.Count)
            {
                throw new ArgumentException("mismatch between number of codomain variables in spatial operator and given codomain mapping");
            }

            m_DomainAndParamFields = ArrayTools.Cat(__DomainFields, _Parameters);
            this.DELTA             = __DomainFields.Count;

            // ------------------------
            // sort equation components
            // ------------------------

            int Gamma = m_CodomainMap.NoOfVariables;

            m_NonlinLsForm_V = DiffOp.GetArgMapping <INonlinLevelSetForm_V>(true,
                                                                            eq => ((eq.LevelSetTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0) && Compfilter(eq),
                                                                            eq => (eq is ILevelSetForm) ? new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq) : null);
            m_NonlinLsForm_GradV = DiffOp.GetArgMapping <INonlinLevelSetForm_GradV>(true,
                                                                                    eq => ((eq.LevelSetTerms & (TermActivationFlags.GradV | TermActivationFlags.UxGradV | TermActivationFlags.GradUxGradV)) != 0) && Compfilter(eq),
                                                                                    eq => (eq is ILevelSetForm) ? new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq) : null);


            m_ValueRequired    = new bool[m_DomainAndParamFields.Length];
            m_GradientRequired = new bool[m_DomainAndParamFields.Length];

            m_NonlinLsForm_V.DetermineReqFields(m_GradientRequired,
                                                comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            m_NonlinLsForm_GradV.DetermineReqFields(m_GradientRequired,
                                                    comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            m_NonlinLsForm_V.DetermineReqFields(m_ValueRequired,
                                                comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));
            m_NonlinLsForm_GradV.DetermineReqFields(m_ValueRequired,
                                                    comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));

            for (int i = __DomainFields.Count; i < m_DomainAndParamFields.Length; i++)
            {
                m_ValueRequired[i] = true; // parameters are always required!
            }


            // -----
            // alloc
            // -----

            Koeff_V     = new MultidimensionalArray[Gamma];
            Koeff_GradV = new MultidimensionalArray[Gamma];
            for (int gamma = 0; gamma < Gamma; gamma++)
            {
                Koeff_V[gamma]     = new MultidimensionalArray(3);
                Koeff_GradV[gamma] = new MultidimensionalArray(4);
            }

            int L = m_DomainAndParamFields.Length;

            m_FieldValuesPos         = new MultidimensionalArray[L];
            m_FieldValuesNeg         = new MultidimensionalArray[L];
            m_FieldGradientValuesPos = new MultidimensionalArray[L];
            m_FieldGradientValuesNeg = new MultidimensionalArray[L];

            for (int l = 0; l < L; l++)
            {
                if (m_ValueRequired[l])
                {
                    m_FieldValuesPos[l] = new MultidimensionalArray(2);
                    m_FieldValuesNeg[l] = new MultidimensionalArray(2);
                }

                if (m_GradientRequired[l])
                {
                    m_FieldGradientValuesPos[l] = new MultidimensionalArray(3);
                    m_FieldGradientValuesNeg[l] = new MultidimensionalArray(3);
                }
            }


            // ------------------
            // init custom timers
            // ------------------

            base.CustomTimers             = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() };
            base.CustomTimers_Names       = new string[] { "Flux-Eval", "Basis-Eval", "Loops", "ParametersAndNormals", "Field-Eval" };
            base.CustomTimers_RootPointer = new int[5];
            ArrayTools.SetAll(base.CustomTimers_RootPointer, -1);

            this.m_NonlinLsForm_V_Watches     = this.m_NonlinLsForm_V.InitStopWatches(0, this);
            this.m_NonlinLsForm_GradV_Watches = this.m_NonlinLsForm_GradV.InitStopWatches(0, this);

            Flux_Eval            = base.CustomTimers[0];
            Basis_Eval           = base.CustomTimers[1];
            Loops                = base.CustomTimers[2];
            ParametersAndNormals = base.CustomTimers[3];
            Field_Eval           = base.CustomTimers[4];
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Usual plotting
 /// </summary>
 protected override void PlotCurrentState(double physTime, TimestepNumber timestepNo, int superSampling = 0)
 {
     Tecplot.PlotFields(
         ArrayTools.Cat <DGField>(f1Gradient_Analytical, f1Gradient_Numerical, f1, GridData.BoundaryMark(), Laplace_f1_Numerical, Laplace_f2_Numerical),
         "derivatives", 0.0, superSampling);
 }
Ejemplo n.º 14
0
        /// <summary>
        /// ctor.
        /// </summary>
        internal NECQuadratureLevelSet(IGridData context,
                                       XSpatialOperatorMk2 DiffOp,
                                       V __ResultVector,
                                       IList <DGField> __DomainFields,
                                       IList <DGField> __Parameters,
                                       UnsetteledCoordinateMapping CodomainMap,
                                       LevelSetTracker lsTrk, int _iLevSet, Tuple <SpeciesId, SpeciesId> SpeciesPair,
                                       ICompositeQuadRule <QuadRule> domAndRule) //
            : base(new int[] { CodomainMap.GetNonXBasisLengths(0).Sum() * 2 },   // we always integrate over species in pairs (neg + pos), so we need to alloc mem only 2 species
                   context,
                   domAndRule)                                                   //
        {
            MPICollectiveWatchDog.Watch();

            // -----------------------------------
            // set members / check ctor parameters
            // -----------------------------------
            m_lsTrk            = lsTrk;
            this.m_LevSetIdx   = _iLevSet;
            this.m_SpeciesPair = SpeciesPair;
            this.ResultVector  = __ResultVector;
            m_CodomainMap      = CodomainMap;
            var _Parameters = (__Parameters != null) ? __Parameters.ToArray() : new DGField[0];

            if (__DomainFields.Count != DiffOp.DomainVar.Count)
            {
                throw new ArgumentException("mismatch between number of domain variables in spatial operator and given domain variables");
            }
            if (_Parameters.Length != DiffOp.ParameterVar.Count)
            {
                throw new ArgumentException("mismatch between number of parameter variables in spatial operator and given parameters");
            }
            if (m_CodomainMap.NoOfVariables != DiffOp.CodomainVar.Count)
            {
                throw new ArgumentException("mismatch between number of codomain variables in spatial operator and given codomain mapping");
            }

            var _DomainAndParamFields = ArrayTools.Cat(__DomainFields, _Parameters);

            this.DELTA = __DomainFields.Count;

            m_DomainAndParamFieldsA = new ConventionalDGField[_DomainAndParamFields.Length];
            m_DomainAndParamFieldsB = new ConventionalDGField[_DomainAndParamFields.Length];
            for (int i = 0; i < m_DomainAndParamFieldsA.Length; i++)
            {
                var f = _DomainAndParamFields[i];
                if (f == null)
                {
                    m_DomainAndParamFieldsA[i] = null;
                    m_DomainAndParamFieldsB[i] = null;
                }
                else if (f is XDGField xf)
                {
                    m_DomainAndParamFieldsA[i] = xf.GetSpeciesShadowField(this.SpeciesA);
                    m_DomainAndParamFieldsB[i] = xf.GetSpeciesShadowField(this.SpeciesB);
                }
                else if (f is ConventionalDGField cf)
                {
                    m_DomainAndParamFieldsA[i] = cf;
                    m_DomainAndParamFieldsB[i] = null;
                }
                else
                {
                    throw new NotImplementedException("missing implementation for " + f.GetType().Name);
                }
            }

            LECQuadratureLevelSet <IMutableMatrix, double[]> .TestNegativeAndPositiveSpecies(domAndRule, m_lsTrk, SpeciesA, SpeciesB, m_LevSetIdx);

            // ------------------------
            // sort equation components
            // ------------------------

            int Gamma = m_CodomainMap.NoOfVariables;

            m_NonlinLsForm_V = EquationComponentArgMapping <INonlinLevelSetForm_V> .GetArgMapping(DiffOp, true,
                                                                                                  eq => ((eq.LevelSetTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0) && Compfilter(eq),
                                                                                                  eq => (eq is ILevelSetForm)?new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq, lsTrk) : null);

            m_NonlinLsForm_GradV = EquationComponentArgMapping <INonlinLevelSetForm_GradV> .GetArgMapping(DiffOp, true,
                                                                                                          eq => ((eq.LevelSetTerms & (TermActivationFlags.GradV | TermActivationFlags.UxGradV | TermActivationFlags.GradUxGradV)) != 0) && Compfilter(eq),
                                                                                                          eq => (eq is ILevelSetForm)?new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq, lsTrk) : null);


            m_ValueRequired    = new bool[m_DomainAndParamFieldsA.Length];
            m_GradientRequired = new bool[m_DomainAndParamFieldsA.Length];

            m_NonlinLsForm_V.DetermineReqFields(m_GradientRequired,
                                                comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            m_NonlinLsForm_GradV.DetermineReqFields(m_GradientRequired,
                                                    comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0));
            m_NonlinLsForm_V.DetermineReqFields(m_ValueRequired,
                                                comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));
            m_NonlinLsForm_GradV.DetermineReqFields(m_ValueRequired,
                                                    comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0));

            for (int i = __DomainFields.Count; i < m_DomainAndParamFieldsA.Length; i++)
            {
                m_ValueRequired[i] = true; // parameters are always required!
            }


            // -----
            // alloc
            // -----

            Koeff_V     = new MultidimensionalArray[Gamma];
            Koeff_GradV = new MultidimensionalArray[Gamma];
            for (int gamma = 0; gamma < Gamma; gamma++)
            {
                Koeff_V[gamma]     = new MultidimensionalArray(3);
                Koeff_GradV[gamma] = new MultidimensionalArray(4);
            }

            Debug.Assert(m_DomainAndParamFieldsA.Length == m_DomainAndParamFieldsB.Length);
            int L = m_DomainAndParamFieldsA.Length;

            m_FieldValuesPos         = new MultidimensionalArray[L];
            m_FieldValuesNeg         = new MultidimensionalArray[L];
            m_FieldGradientValuesPos = new MultidimensionalArray[L];
            m_FieldGradientValuesNeg = new MultidimensionalArray[L];

            for (int l = 0; l < L; l++)
            {
                if (m_ValueRequired[l])
                {
                    m_FieldValuesPos[l] = new MultidimensionalArray(2);
                    m_FieldValuesNeg[l] = new MultidimensionalArray(2);
                }

                if (m_GradientRequired[l])
                {
                    m_FieldGradientValuesPos[l] = new MultidimensionalArray(3);
                    m_FieldGradientValuesNeg[l] = new MultidimensionalArray(3);
                }
            }


            // ------------------
            // init custom timers
            // ------------------

            base.CustomTimers             = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() };
            base.CustomTimers_Names       = new string[] { "Flux-Eval", "Basis-Eval", "Loops", "ParametersAndNormals", "Field-Eval" };
            base.CustomTimers_RootPointer = new int[5];
            ArrayTools.SetAll(base.CustomTimers_RootPointer, -1);

            this.m_NonlinLsForm_V_Watches     = this.m_NonlinLsForm_V.InitStopWatches(0, this);
            this.m_NonlinLsForm_GradV_Watches = this.m_NonlinLsForm_GradV.InitStopWatches(0, this);

            Flux_Eval            = base.CustomTimers[0];
            Basis_Eval           = base.CustomTimers[1];
            Loops                = base.CustomTimers[2];
            ParametersAndNormals = base.CustomTimers[3];
            Field_Eval           = base.CustomTimers[4];
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Create Spatial Operators and build the corresponding Matrices
        /// </summary>
        public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield)
        {
            OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength];

            OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping);
            OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength];


            //LevelSetTracker.GetLevelSetGradients(0,);

            // bulk part of the matrix
            //Operator_bulk.ComputeMatrix(
            //    Extension.Mapping,
            //    LevelSetGradient.ToArray(),
            //    Extension.Mapping,
            //    OpMatrix_bulk, OpAffine_bulk,
            //    OnlyAffine: false, sgrd: null);

            switch (Control.FluxVariant)
            {
            case FluxVariant.GradientBased:
                // Flux Direction based on Mean Level Set Gradient
                BulkParams = new List <DGField> {
                };                                      // Hack, to make ArrayTools.Cat produce a List of DGFields
                // second Hack: Does only work, when InterfaceParams is according to a single component flux,
                // else, we will have to change the boundary edge flux
                BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray());
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);
                break;

            case FluxVariant.ValueBased:
                // Flux Direction Based on Cell-Averaged Level-Set Value
                BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet);
                MeanLevelSet.Clear();
                MeanLevelSet.AccLaidBack(1.0, Phi);
                break;

            case FluxVariant.SWIP:
                BulkParams = LevelSetGradient.ToArray();
                break;

            default:
                throw new Exception();
            }

            // Build Operator

            Operator_bulk.ComputeMatrixEx(Extension.Mapping,
                                          BulkParams,
                                          Extension.Mapping,
                                          OpMatrix_bulk, OpAffine_bulk,
                                          OnlyAffine: false,
                                          time: 0.0,
                                          edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null),
                                          volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null)
                                          );

            Operator_interface.ComputeMatrixEx(
                LevelSetTracker,
                Extension.Mapping,
                InterfaceParams,
                Extension.Mapping,
                OpMatrix_interface,
                OpAffine_interface,
                OnlyAffine: false,
                time: 0,
                MPIParameterExchange: false,
                whichSpc: LevelSetTracker.GetSpeciesId("A")
                );
#if DEBUG
            OpMatrix_bulk.CheckForNanOrInfM();
            OpAffine_bulk.CheckForNanOrInfV();

            OpMatrix_interface.CheckForNanOrInfM();
            OpAffine_interface.CheckForNanOrInfV();
#endif

            //Only for Debugging purposes
            //OpMatrix.SaveToTextFileSparse("C:\\tmp\\EllipticReInit.txt");

            Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0");
            Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0");
#if DEBUG
            //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() );
#endif
            OpMatrix.Clear();
            OpMatrix.Acc(1.0, OpMatrix_bulk);
            OpMatrix.Acc(1.0, OpMatrix_interface);
            //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation());
            OpMatrix.AssumeSymmetric = false;

            OpAffine.Clear();
            OpAffine.AccV(1.0, OpAffine_bulk);
            OpAffine.AccV(1.0, OpAffine_interface);
#if DEBUG
            //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest());
#endif
        }
Ejemplo n.º 16
0
        /// <summary>
        ///
        /// </summary>
        public void AssembleMatrix_Timestepper <T>(
            int CutCellQuadOrder,
            BlockMsrMatrix OpMatrix, double[] OpAffine,
            Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales,
            IEnumerable <T> U0,
            VectorField <SinglePhaseField> SurfaceForce,
            VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature,
            UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
            double time) where T : DGField
        {
            if (ColMapping.BasisS.Count != this.Op.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.Op.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            // check:
            var Tracker = this.LsTrk;
            int D       = Tracker.GridDat.SpatialDimension;

            if (U0 != null && U0.Count() != D)
            {
                throw new ArgumentException();
            }


            LevelSet Phi = (LevelSet)(Tracker.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();


            // parameter assembly
            // ==================

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(Tracker, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]),
                Normals);

            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }

            // assemble the matrix & affine vector
            // ===================================

            // compute matrix
            Op.ComputeMatrixEx(Tracker,
                               ColMapping, Params, RowMapping,
                               OpMatrix, OpAffine, false, time, true,
                               AgglomeratedCellLengthScales,
                               SpcToCompute);
        }
Ejemplo n.º 17
0
        /// <summary>
        ///
        /// </summary>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time,
                                       int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce,
                                       VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature,
                                       bool[] updateSolutionParams = null, DGField[] ExtParams = null) where T : DGField
        {
            //IEnumerable<T> CoupledCurrentState = null, IEnumerable<T> CoupledParams = null) where T : DGField {

            // checks:
            if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            int D = this.LsTrk.GridDat.SpatialDimension;

            if (CurrentState != null && !config.solveEnergy && !config.solveHeat && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }

            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            // parameter assembly
            // ==================
            #region param assembly

            LevelSet    Phi          = (LevelSet)(this.LsTrk.LevelSets[0]);
            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();


            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);
                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // linearization velocity:
            //if (this.U0meanrequired) {
            //    VectorField<XDGField> U0mean = new VectorField<XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

            //    U0mean.Clear();
            //    if (this.physParams.IncludeConvection)
            //        ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
            //}


            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;
            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }


            // velocity gradient vectors
            var       VelMap   = new CoordinateMapping(U0);
            DGField[] VelParam = VelMap.Fields.ToArray();

            VectorField <DGField> GradVelX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((VelParam[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelX.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((VelParam[1] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelY.ForEach(F => F.CheckForNanOrInf(true, true, true));


            VectorField <DGField> GradVelXGradX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradX_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelX[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelXGradX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelXGradX.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelXGradY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradY_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelX[1] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelXGradY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelXGradY.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelYGradX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradX_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelY[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelYGradX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelYGradX.ForEach(F => F.CheckForNanOrInf(true, true, true));

            VectorField <DGField> GradVelYGradY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradY_Gradient", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((GradVelY[1] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (GradVelYGradY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            GradVelYGradY.ForEach(F => F.CheckForNanOrInf(true, true, true));



            // pressure and gradient
            var       PressMap   = new CoordinateMapping(CurrentState.ToArray()[D]);
            DGField[] PressParam = PressMap.Fields.ToArray();

            VectorField <DGField> PressGrad = new VectorField <DGField>(D, PressParam[0].Basis, "PressureGrad", XDGField.Factory);
            for (int d = 0; d < D; d++)
            {
                foreach (var Spc in this.LsTrk.SpeciesIdS)
                {
                    DGField f_Spc = ((PressParam[0] as XDGField).GetSpeciesShadowField(Spc));
                    SubGrid sf    = this.LsTrk.Regions.GetSpeciesSubGrid(Spc);
                    (PressGrad[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf);
                }
            }
            PressGrad.ForEach(F => F.CheckForNanOrInf(true, true, true));

            // gravity
            var       GravMap   = new CoordinateMapping(ExtParams);
            DGField[] GravParam = GravMap.Fields.ToArray();


            // heat flux for evaporation
            DGField[] HeatFluxParam = new DGField[D];
            if (config.solveHeat)
            {
                if (config.conductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP && updateSolutionParams[D + 1])
                {
                    HeatFluxParam = new VectorField <XDGField>(D, CurrentState.ToArray()[D + 1].Basis, "HeatFlux0_", XDGField.Factory).ToArray();
                    Dictionary <string, double> kSpc = new Dictionary <string, double>();
                    kSpc.Add("A", -thermParams.k_A);
                    kSpc.Add("B", -thermParams.k_B);
                    XNSEUtils.ComputeGradientForParam(CurrentState.ToArray()[D + 1], HeatFluxParam, this.LsTrk, kSpc, this.LsTrk.Regions.GetCutCellSubGrid());
                }
                else if (config.conductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP && updateSolutionParams[D + 2])
                {
                    var HeatFluxMap = new CoordinateMapping(CurrentState.ToArray().GetSubVector(D + 2, D));
                    HeatFluxParam = HeatFluxMap.Fields.ToArray();
                }
                else
                {
                    HeatFluxParam = storedParams.GetSubVector(2 * D + 4, D);
                }
            }
            if (ExtParams != null)
            {
                HeatFluxParam = ExtParams;
            }

            #endregion


            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Normals,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]));

            if (config.solveEnergy)
            {
                Params = ArrayTools.Cat <DGField>(Params.ToArray <DGField>(),
                                                  GradVelX,
                                                  GradVelY,
                                                  GradVelXGradX,
                                                  GradVelXGradY,
                                                  GradVelYGradX,
                                                  GradVelYGradY,
                                                  PressParam,
                                                  PressGrad,
                                                  GravMap);
            }

            if (config.solveHeat)
            {
                Params = ArrayTools.Cat <DGField>(Params.ToArray <DGField>(),
                                                  CurrentState.ToArray <DGField>().GetSubVector(D + 1, 1),
                                                  HeatFluxParam,
                                                  new SinglePhaseField[1]);
            }


            // store old params
            for (int p = 0; p < Params.Length; p++)
            {
                if (Params[p] != null)
                {
                    storedParams[p] = Params[p].CloneAs();
                }
            }



            // advanced settings for the navier slip boundary condition
            // ========================================================


            CellMask SlipArea;
            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;
            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);
            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // interface coefficients
            // ======================

            MultidimensionalArray lambdaI, muI;
            lambdaI = SlipLengths.CloneAs();
            lambdaI.Clear();
            muI = SlipLengths.CloneAs();
            muI.Clear();

            foreach (Chunk cnk in this.LsTrk.Regions.GetCutCellMask())
            {
                for (int i = cnk.i0; i < cnk.JE; i++)
                {
                    double lI = 0.0;
                    double mI = 0.0;

                    // do the magic!!!
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] > 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] > 0)
                    {
                    }
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] > 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] < 0)
                    {
                        //lI = config.physParams.Sigma;
                        mI = config.physParams.Sigma;
                    }
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] < 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] < 0)
                    {
                        //lI = -config.physParams.Sigma;
                        mI = -config.physParams.Sigma;
                    }
                    if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] < 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] > 0)
                    {
                        //lI = 10 * config.physParams.Sigma;
                        mI = 10 * config.physParams.Sigma;
                    }

                    lambdaI[i] = lI;
                    muI[i]     = mI;
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;

            BitArray EvapMicroRegion = this.LsTrk.GridDat.GetBoundaryCells().GetBitMask();
            EvapMicroRegion.SetAll(false);

            // compute matrix
            if (OpMatrix != null)
            {
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.CellLengthScales[kv.Key] = kv.Value;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["SlipLengths"]     = SlipLengths;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["EvapMicroRegion"] = EvapMicroRegion;
                    if (config.prescribedMassflux != null)
                    {
                        double[] dummyX = new double[] { 0.0, 0.0 };
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["prescribedMassflux"] = config.prescribedMassflux(dummyX, time);
                    }
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["InterfaceLengths"] = kv.Value;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["lambda_interface"] = lambdaI;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["mu_interface"]     = muI;
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                      CurrentState.ToArray(), Params, RowMapping);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.CellLengthScales[kv.Key] = kv.Value;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["SlipLengths"]     = SlipLengths;
                    this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["EvapMicroRegion"] = EvapMicroRegion;
                    if (config.prescribedMassflux != null)
                    {
                        double[] dummyX = new double[] { 0.0, 0.0 };
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["prescribedMassflux"] = config.prescribedMassflux(dummyX, time);
                    }
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["InterfaceLengths"] = kv.Value;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["lambda_interface"] = lambdaI;
                        this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["mu_interface"]     = muI;
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="OpMatrix"></param>
        /// <param name="OpAffine"></param>
        /// <param name="RowMapping"></param>
        /// <param name="ColMapping"></param>
        /// <param name="CurrentState"></param>
        /// <param name="AgglomeratedCellLengthScales"></param>
        /// <param name="time"></param>
        /// <param name="CutCellQuadOrder"></param>
        /// <param name="SurfaceForce"></param>
        /// <param name="LevelSetGradient"></param>
        /// <param name="ExternalyProvidedCurvature"></param>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time,
                                       int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce,
                                       VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature, double currentWeissenberg,
                                       IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField
        {
            // checks:
            if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            int D = this.LsTrk.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 4))
            {
                throw new ArgumentException();
            }

            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }

            DGField[] Stress0;
            Stress0 = CurrentState.Skip(D + 1).Take(3).ToArray();

            if (U0.Count() != D)
            {
                throw new ArgumentException("Spatial dimesion and number of velocity parameter components does not match!");
            }

            if (Stress0.Count() != D + 1)
            {
                throw new ArgumentException("Spatial dimesion and number of stress parameter components does not match!");
            }



            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);
            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // parameter assembly
            // ==================

            LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }


            // Velocity and stresses for linearization

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }


            if (VelocityXGradient == null)
            {
                VelocityXGradient = new VectorField <XDGField>(D, CurrentState.ElementAt(0).Basis, "VelocityX_Gradient", XDGField.Factory);
            }
            if (VelocityYGradient == null)
            {
                VelocityYGradient = new VectorField <XDGField>(D, CurrentState.ElementAt(1).Basis, "VelocityY_Gradient", XDGField.Factory);
            }


            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                VelocityXGradient,
                VelocityYGradient,
                Stress0,
                //artificalViscosity,
                Normals,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]));


            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;

            BitArray EvapMicroRegion = this.LsTrk.GridDat.GetBoundaryCells().GetBitMask();

            EvapMicroRegion.SetAll(false);

            // compute matrix
            if (OpMatrix != null)
            {
                if (!useJacobianForOperatorMatrix)
                {
                    XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);
                    this.ParameterUpdate(CurrentState, Params, CutCellQuadOrder, AgglomeratedCellLengthScales);

                    foreach (var kv in AgglomeratedCellLengthScales)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = this.LsTrk.GridDat.Edges.h_max_Edge;
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    }

                    if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                    {
                        foreach (var kv in InterfaceLengths)
                        {
                            mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                        }
                    }

                    mtxBuilder.time = time;
                    mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);

                    foreach (var kv in AgglomeratedCellLengthScales)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg);
                    }
                }
                else
                {
                    throw new NotImplementedException("The FDbuilder for the Jacobian is missing for the XSpatial Opearator!");
                    // Finite Difference Linearization
                    //XSpatialOperatorMk2.XEvaluatorLinear FDBuilder = this.m_XOp.GetFDJacobianBuilder(domMap, Params, codMap, this.ParameterUpdate);

                    //foreach (var kv in AgglomeratedCellLengthScales) {
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    //}

                    //if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) {
                    //    foreach (var kv in InterfaceLengths) {
                    //        FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    //    }
                    //}
                    //FDbuilder.time = time;

                    //FDbuilder.ComputeMatrix(OpMatrix, OpAffine);

                    //// FDJacobian has (Mx +b) as RHS, for unsteady calc. we must subtract Mx for real affine Vector!
                    //OpMatrix.SpMV(-1.0, new CoordinateVector(CurrentState), 1.0, OpAffine);

                    //foreach (var kv in AgglomeratedCellLengthScales) {
                    //    FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg);
                    //}
                }
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                      CurrentState.ToArray(), Params, RowMapping,
                                                                                      SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = this.LsTrk.GridDat.Edges.h_max_Edge;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
Ejemplo n.º 19
0
        public static IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0)
        {
            IBM_Control C = new IBM_Control();

            const double BaseSize = 1.0;

            // basic database options
            // ====================

            C.savetodb           = false;
            C.ProjectDescription = "Cylinder";
            C.Tags.Add("with immersed boundary method");

            // DG degrees
            // ==========

            C.FieldOptions.Add("VelocityX", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("VelocityY", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Pressure", new FieldOpts()
            {
                Degree   = k - 1,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("PhiDG", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Phi", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });

            // grid and boundary conditions
            // ============================

            C.GridFunc = delegate {
                var _xNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1, false);
                _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1));
                var _xNodes2 = GenericBlas.Linspace(1, 5.5, 35);
                _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1));
                var _xNodes3 = Grid1D.TanhSpacing(5.5, 22, 20, 1.3, true);

                var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3);


                var _yNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1.2, false);
                _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                var _yNodes2 = GenericBlas.Linspace(1, 3, 20);
                _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                var _yNodes3 = Grid1D.TanhSpacing(3, 4.1, 5, 1.2, true);

                var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);

                var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic);
                grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                if (!xPeriodic)
                {
                    grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                    grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                }

                grd.DefineEdgeTags(delegate(double[] X) {
                    byte et = 0;
                    if (Math.Abs(X[1] - (0 * BaseSize)) <= 1.0e-8)
                    {
                        et = 1;
                    }
                    if (Math.Abs(X[1] + (-4.1 * BaseSize)) <= 1.0e-8)
                    {
                        et = 2;
                    }
                    if (!xPeriodic && Math.Abs(X[0] - (0 * BaseSize)) <= 1.0e-8)
                    {
                        et = 3;
                    }
                    if (!xPeriodic && Math.Abs(X[0] + (-22 * BaseSize)) <= 1.0e-8)
                    {
                        et = 4;
                    }


                    Debug.Assert(et != 0);
                    return(et);
                });

                return(grd);
            };

            C.AddBoundaryValue("Velocity_Inlet_upper", "VelocityX", X => 0);
            C.AddBoundaryValue("Velocity_Inlet_lower", "VelocityX", X => 0);
            if (!xPeriodic)
            {
                C.AddBoundaryValue("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1)));
            }
            C.AddBoundaryValue("Pressure_Outlet_right");

            // Initial Values
            // ==============

            C.particleRadius = 0.5;

            C.InitialValues_Evaluators.Add("Phi", X => - (X[0] - 2).Pow2() + -(X[1] - 2).Pow2() + C.particleRadius.Pow2());


            C.InitialValues_Evaluators.Add("VelocityX", X => 0);


            // Physical Parameters
            // ===================

            C.PhysicalParameters.mu_A  = 0.05;
            C.PhysicalParameters.rho_A = 1;

            C.PhysicalParameters.IncludeConvection = true;
            C.PhysicalParameters.Material          = true;

            // misc. solver options
            // ====================

            C.AdvancedDiscretizationOptions.PenaltySafety = 1;
            C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.1;
            C.LevelSetSmoothing        = false;
            C.MaxKrylovDim             = 20;
            C.MaxSolverIterations      = 100;
            C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;
            C.NoOfMultigridLevels      = 1;

            // Timestepping
            // ============

            C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2;
            double dt = 1E20;

            C.dtFixed       = dt;
            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 200;
            C.NoOfTimesteps = 1;

            // haben fertig...
            // ===============

            return(C);
        }
Ejemplo n.º 20
0
        void ParameterUpdate(IEnumerable <DGField> CurrentState, IEnumerable <DGField> ParameterVar, int CutCellQuadOrder, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales)
        {
            LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }

            DGField[] Stress0;
            Stress0 = CurrentState.Skip(D + 1).Take(3).ToArray();

            if (U0.Count() != D)
            {
                throw new ArgumentException("Spatial dimesion and number of velocity parameter components does not match!");
            }

            if (Stress0.Count() != D + 1)
            {
                throw new ArgumentException("Spatial dimesion and number of stress parameter components does not match!");
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);

                U0mean.Clear();
                ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }


            //if (this.Control.SetParamsAnalyticalSol == false) {
            //SinglePhaseField[] __VelocityXGradient = ParameterVar.Skip(2 * D).Take(D).Select(f => f as SinglePhaseField).ToArray();
            //SinglePhaseField[] __VelocityYGradient = ParameterVar.Skip(3 * D).Take(D).Select(f => f as SinglePhaseField).ToArray();
            //Debug.Assert(ArrayTools.AreEqual(__VelocityXGradient, VelocityXGradient.ToArray(), (fa, fb) => object.ReferenceEquals(fa, fb)));
            //Debug.Assert(ArrayTools.AreEqual(__VelocityYGradient, VelocityYGradient.ToArray(), (fa, fb) => object.ReferenceEquals(fa, fb)));

            //if (VelocityXGradient == null) {
            //    VelocityXGradient = new VectorField<XDGField>(D, CurrentState.ElementAt(0).Basis, "VelocityX_Gradient", XDGField.Factory);
            //}
            VelocityXGradient.Clear();
            VelocityXGradient.GradientByFlux(1.0, U0[0]);
            //if (VelocityYGradient == null) {
            //    VelocityYGradient = new VectorField<XDGField>(D, CurrentState.ElementAt(1).Basis, "VelocityY_Gradient", XDGField.Factory);
            //}
            VelocityYGradient.Clear();
            VelocityYGradient.GradientByFlux(1.0, U0[1]);
            //}

            if (this.useArtificialDiffusion == true)
            {
                throw new NotImplementedException("artificial diffusion not jet fully implemented...");
                //SinglePhaseField __ArtificialViscosity = ParameterVar.Skip(5 * D + 1).Take(1).Select(f => f as SinglePhaseField).ToArray()[0];
                //if (!object.ReferenceEquals(this.artificalViscosity, __ArtificialViscosity))
                //    throw new ApplicationException();

                //ArtificialViscosity.ProjectArtificalViscosityToDGField(__ArtificialViscosity, perssonsensor, this.Control.SensorLimit, artificialMaxViscosity);
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        ///
        /// </summary>
        public void AssembleMatrix_Timestepper <T>(
            int CutCellQuadOrder,
            BlockMsrMatrix OpMatrix, double[] OpAffine,
            Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales,
            IEnumerable <T> CurrentState,
            VectorField <SinglePhaseField> SurfaceForce,
            VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature,
            UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
            double time, IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField
        {
            if (ColMapping.BasisS.Count != this.Op.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.Op.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            // check:
            var Tracker = this.LsTrk;
            int D       = Tracker.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }
            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }
            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            LevelSet Phi = (LevelSet)(Tracker.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;


            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);

            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }



            // parameter assembly
            // ==================

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(Tracker, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // Temperature gradient for evaporation
            VectorField <DGField> GradTemp = new VectorField <DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory);

            if (CoupledCurrentState != null)
            {
                DGField Temp = CoupledCurrentState.ToArray()[0];
                GradTemp = new VectorField <DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory);
                XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk);
            }

            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]),
                Normals,
                ((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]),
                ((evaporation) ? CoupledCurrentState.ToArray <DGField>() : new SinglePhaseField[1]),
                ((evaporation) ? CoupledParams.ToArray <DGField>() : new SinglePhaseField[1]));  //((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]));

            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            // compute matrix
            if (OpMatrix != null)
            {
                //Op.ComputeMatrixEx(Tracker,
                //    ColMapping, Params, RowMapping,
                //    OpMatrix, OpAffine, false, time, true,
                //    AgglomeratedCellLengthScales,
                //    InterfaceLengths, SlipLengths,
                //    SpcToCompute);

                XSpatialOperator.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    if (evaporation)
                    {
                        BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count);;  // this.LsTrk.GridDat.GetBoundaryCells().GetBitMask();
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    }
                }

                if (Op.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);

#if DEBUG
                // remark: remove this piece in a few months from now on (09may18) if no problems occur
                {
                    BlockMsrMatrix checkOpMatrix = new BlockMsrMatrix(RowMapping, ColMapping);
                    double[]       checkAffine   = new double[OpAffine.Length];

                    Op.ComputeMatrixEx(Tracker,
                                       ColMapping, Params, RowMapping,
                                       OpMatrix, OpAffine, false, time, true,
                                       AgglomeratedCellLengthScales,
                                       InterfaceLengths, SlipLengths,
                                       SpcToCompute);


                    double[] checkResult = checkAffine.CloneAs();
                    var      currentVec  = new CoordinateVector(CurrentState.ToArray());
                    checkOpMatrix.SpMV(1.0, new CoordinateVector(CurrentState.ToArray()), 1.0, checkResult);

                    double L2_dist = GenericBlas.L2DistPow2(checkResult, OpAffine).MPISum().Sqrt();
                    double RefNorm = (new double[] { checkResult.L2NormPow2(), OpAffine.L2NormPow2(), currentVec.L2NormPow2() }).MPISum().Max().Sqrt();

                    Assert.LessOrEqual(L2_dist, RefNorm * 1.0e-6);
                    Debug.Assert(L2_dist < RefNorm * 1.0e-6);
                }
#endif
            }
            else
            {
                XSpatialOperator.XEvaluatorNonlin eval = Op.GetEvaluatorEx(Tracker,
                                                                           CurrentState.ToArray(), Params, RowMapping,
                                                                           SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                    if (evaporation)
                    {
                        BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count);
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion);
                    }
                }

                if (Op.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }


            // check
            // =====

            /*
             * {
             *  DGField[] testDomainFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray();
             *  CoordinateVector test = new CoordinateVector(testDomainFieldS);
             *
             *  DGField[] errFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray();
             *  CoordinateVector Err = new CoordinateVector(errFieldS);
             *
             *  var eval = Op.GetEvaluatorEx(LsTrk,
             *      testDomainFieldS, Params, RowMapping);
             *
             *  foreach (var s in this.LsTrk.SpeciesIdS)
             *      eval.SpeciesOperatorCoefficients[s].CellLengthScales = AgglomeratedCellLengthScales[s];
             *
             *  eval.time = time;
             *  int L = test.Count;
             *  Random r = new Random();
             *  for(int i = 0; i < L; i++) {
             *      test[i] = r.NextDouble();
             *  }
             *
             *
             *
             *  double[] R1 = new double[L];
             *  double[] R2 = new double[L];
             *  eval.Evaluate(1.0, 1.0, R1);
             *
             *  R2.AccV(1.0, OpAffine);
             *  OpMatrix.SpMV(1.0, test, 1.0, R2);
             *
             *  Err.AccV(+1.0, R1);
             *  Err.AccV(-1.0, R2);
             *
             *  double ErrDist = GenericBlas.L2DistPow2(R1, R2).MPISum().Sqrt();
             *
             *  double Ref = test.L2NormPow2().MPISum().Sqrt();
             *
             *  Debug.Assert(ErrDist <= Ref*1.0e-5, "Mismatch between explicit evaluation of XDG operator and matrix.");
             * }
             */
        }
Ejemplo n.º 22
0
        /// <summary>
        /// ctor for the operator factory, where the equation compnents are set
        /// </summary>
        /// <param name="config"></param>
        /// <param name="_LsTrk"></param>
        /// <param name="_HMFdegree"></param>
        /// <param name="BcMap"></param>
        /// <param name="degU"></param>
        public XRheology_OperatorFactory(XRheology_OperatorConfiguration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int _stressDegree, int degU)
        {
            this.LsTrk = _LsTrk;
            this.D     = _LsTrk.GridDat.SpatialDimension;

            this.HMFDegree = _HMFdegree;

            this.physParams = config.getPhysParams;
            this.dntParams  = config.getDntParams;
            this.useJacobianForOperatorMatrix = config.isUseJacobian;
            this.useArtificialDiffusion       = config.isUseArtificialDiffusion;


            // test input
            // ==========
            {
                if (config.getDomBlocks.GetLength(0) != 3 || config.getCodBlocks.GetLength(0) != 3)
                {
                    throw new ArgumentException();
                }

                //if ((config.getPhysParams.Weissenberg_a <= 0) && (config.getPhysParams.Weissenberg_a <= 0)) {
                //    config.isOldroydB = false;
                //} else {
                //    if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0))
                //        throw new ArgumentException();
                //}

                //if ((config.getPhysParams.reynolds_A <= 0) && (config.getPhysParams.reynolds_B <= 0)) {
                //    config.isViscous = false;
                //} else {
                //    if ((config.getPhysParams.reynolds_A <= 0) || (config.getPhysParams.reynolds_B <= 0))
                //    throw new ArgumentException();

                //if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.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 = ArrayTools.Cat(EquationNames.MomentumEquations(this.D), EquationNames.ContinuityEquation, EquationNames.Constitutive(this.D));
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(this.D),
                VariableNames.Velocity0MeanVector(this.D),
                VariableNames.VelocityX_GradientVector(),
                VariableNames.VelocityY_GradientVector(),
                VariableNames.StressXXP,
                VariableNames.StressXYP,
                VariableNames.StressYYP,
                // "artificialViscosity",
                VariableNames.NormalVector(this.D),
                VariableNames.Curvature,
                VariableNames.SurfaceForceVector(this.D)
                );
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(this.D), VariableNames.Pressure, VariableNames.StressXX, VariableNames.StressXY, VariableNames.StressYY);


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

            if (config.getDomBlocks[0])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, this.D));
            }
            if (config.getDomBlocks[1])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D, 1));
            }
            if (config.getDomBlocks[2])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D + 1, 3));
            }


            // create Operator
            // ===============
            m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray());

            // add components
            // ============================

            // species bulk components
            for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++)
            {
                // Navier Stokes equations
                XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired);

                // continuity equation
                if (config.isContinuity)
                {
                    XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap);
                }

                // constitutive equation
                XConstitutiveOperatorComponentsFactory.AddSpeciesConstitutive(m_XOp, config, this.D, stressDegree, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired);
            }

            // interface components
            XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, this.D, BcMap, LsTrk);                                                          // surface stress tensor
            XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, this.D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force
            XConstitutiveOperatorComponentsFactory.AddInterfaceConstitutive(m_XOp, config, this.D, BcMap, LsTrk);                                     //viscosity of stresses at constitutive

            if (config.isContinuity)
            {
                XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, this.D, LsTrk);       // continuity equation
            }
            m_XOp.Commit();
        }
Ejemplo n.º 23
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="OpMatrix"></param>
        /// <param name="OpAffine"></param>
        /// <param name="RowMapping"></param>
        /// <param name="ColMapping"></param>
        /// <param name="CurrentState"></param>
        /// <param name="AgglomeratedCellLengthScales"></param>
        /// <param name="time"></param>
        /// <param name="CutCellQuadOrder"></param>
        /// <param name="SurfaceForce"></param>
        /// <param name="LevelSetGradient"></param>
        /// <param name="ExternalyProvidedCurvature"></param>
        public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine,
                                       UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping,
                                       IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time,
                                       int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce,
                                       VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature) where T : DGField
        {
            // checks:
            if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count)
            {
                throw new ArgumentException();
            }
            if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count)
            {
                throw new ArgumentException();
            }

            int D = this.LsTrk.GridDat.SpatialDimension;

            if (CurrentState != null && CurrentState.Count() != (D + 1))
            {
                throw new ArgumentException();
            }

            if (OpMatrix == null && CurrentState == null)
            {
                throw new ArgumentException();
            }

            DGField[] U0;
            if (CurrentState != null)
            {
                U0 = CurrentState.Take(D).ToArray();
            }
            else
            {
                U0 = null;
            }



            // advanced settings for the navier slip boundary condition
            // ========================================================

            CellMask SlipArea;

            switch (this.dntParams.GNBC_Localization)
            {
            case NavierSlip_Localization.Bulk: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask;
                break;
            }

            case NavierSlip_Localization.ContactLine: {
                SlipArea = null;
                break;
            }

            case NavierSlip_Localization.Nearband: {
                SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth));
                break;
            }

            case NavierSlip_Localization.Prescribed: {
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentException();
            }


            MultidimensionalArray SlipLengths;

            SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs();
            SlipLengths.Clear();
            //SlipLengths.AccConstant(-1.0);
            if (SlipArea != null)
            {
                foreach (Chunk cnk in SlipArea)
                {
                    for (int i = cnk.i0; i < cnk.JE; i++)
                    {
                        switch (this.dntParams.GNBC_SlipLength)
                        {
                        case NavierSlip_SlipLength.hmin_DG: {
                            int degU = ColMapping.BasisS.ToArray()[0].Degree;
                            SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1);
                            break;
                        }

                        case NavierSlip_SlipLength.hmin_Grid: {
                            SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i];
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_SlipLength: {
                            SlipLengths[i] = this.physParams.sliplength;
                            break;
                        }

                        case NavierSlip_SlipLength.Prescribed_Beta: {
                            SlipLengths[i] = -1.0;
                            break;
                        }
                        }
                    }
                }
            }


            // parameter assembly
            // ==================

            LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]);

            SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray();

            // normals:
            SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions.
            if (this.NormalsRequired)
            {
                if (LevelSetGradient == null)
                {
                    LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory);
                    LevelSetGradient.Gradient(1.0, Phi);
                }
                Normals = LevelSetGradient.ToArray();
            }
            else
            {
                Normals = new SinglePhaseField[D];
            }

            // curvature:
            SinglePhaseField Curvature;

            if (this.CurvatureRequired)
            {
                Curvature = ExternalyProvidedCurvature;
            }
            else
            {
                Curvature = null;
            }

            // linearization velocity:
            DGField[] U0_U0mean;
            if (this.U0meanrequired)
            {
                XDGBasis U0meanBasis          = new XDGBasis(this.LsTrk, 0);
                VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory);

                U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean);
            }
            else
            {
                U0_U0mean = new DGField[2 * D];
            }

            // Temperature gradient for evaporation
            //VectorField<DGField> GradTemp = new VectorField<DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory);
            //if (CoupledCurrentState != null) {
            //    DGField Temp = CoupledCurrentState.ToArray()[0];
            //    GradTemp = new VectorField<DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory);
            //    XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk);
            //}

            // concatenate everything
            var Params = ArrayTools.Cat <DGField>(
                U0_U0mean,
                Normals,
                Curvature,
                ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]));

            // linearization velocity:
            if (this.U0meanrequired)
            {
                VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray());

                U0mean.Clear();
                if (this.physParams.IncludeConvection)
                {
                    ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper);
                }
            }



            // assemble the matrix & affine vector
            // ===================================

            IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea;

            // compute matrix
            if (OpMatrix != null)
            {
                XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                mtxBuilder.time = time;

                mtxBuilder.ComputeMatrix(OpMatrix, OpAffine);
            }
            else
            {
                XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk,
                                                                                      CurrentState.ToArray(), Params, RowMapping,
                                                                                      SpcToCompute);

                foreach (var kv in AgglomeratedCellLengthScales)
                {
                    eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = kv.Value;
                    eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths);
                }

                if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0)
                {
                    foreach (var kv in InterfaceLengths)
                    {
                        eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value);
                    }
                }

                eval.time = time;

                eval.Evaluate(1.0, 1.0, OpAffine);
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Control for the testcase according to Smolianksi
        /// </summary>
        /// <param name="p"></param>
        /// <param name="kelem"></param>
        /// <param name="_DbPath"></param>
        /// <returns></returns>
        public static XNSE_Control RT_Smolianski(int p = 2, int kelem = 32, string _DbPath = null)
        {
            XNSE_Control C = new XNSE_Control();

            // basic database options
            // ======================
            #region db

            //_DbPath = @"D:\local\local_Testcase_databases\Testcase_RTinstability";
            _DbPath = @"\\fdyprime\userspace\smuda\cluster\cluster_db";

            C.DbPath      = _DbPath;
            C.savetodb    = C.DbPath != null;
            C.ProjectName = "XNSE/RT-Instability";
            C.Tags.Add("unstable");
            //C.Tags.Add("smolianski");

            #endregion

            //C.LogValues = XNSE_Control.LoggingValues.Wavelike;
            //C.WriteInterfaceP = true;


            // DG degrees
            // ==========
            #region degrees

            C.FieldOptions.Add("VelocityX", new FieldOpts()
            {
                Degree   = p,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("VelocityY", new FieldOpts()
            {
                Degree   = p,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Pressure", new FieldOpts()
            {
                Degree   = p - 1,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("PhiDG", new FieldOpts()
            {
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Phi", new FieldOpts()
            {
                Degree   = 4,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Curvature", new FieldOpts()
            {
                Degree   = 8,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });

            #endregion


            // grid genration
            // ==============
            #region grid

            double L = 1;
            double H = 4.0 * L;

            C.GridFunc = delegate() {
                // Smolianski
                //double[] Xnodes = GenericBlas.Linspace(0, L, kelem + 1);
                //double[] Ynodes = GenericBlas.Linspace(0, H, (4 * kelem) + 1);
                //var grd = Grid2D.Cartesian2DGrid(Xnodes, Ynodes, periodicX: false);

                double[] xNodes = GenericBlas.Linspace(0, L, kelem + 1);

                double[] _yNodes1 = GenericBlas.Linspace(0, 2.2, (int)(2.2 * kelem) + 1);
                _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                var _yNodes2 = Grid1D.TanhSpacing(2.2, 4.0, (kelem / 2) + 1, 1.5, true);

                var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2);


                var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: false);

                grd.EdgeTagNames.Add(1, "wall_lower");
                grd.EdgeTagNames.Add(2, "wall_upper");
                grd.EdgeTagNames.Add(3, "freeslip_left");
                grd.EdgeTagNames.Add(4, "freeslip_right");


                grd.DefineEdgeTags(delegate(double[] X) {
                    byte et = 0;
                    if (Math.Abs(X[1]) <= 1.0e-8)
                    {
                        et = 1;
                    }
                    if (Math.Abs(X[1] - H) <= 1.0e-8)
                    {
                        et = 2;
                    }
                    if (Math.Abs(X[0]) <= 1.0e-8)
                    {
                        et = 3;
                    }
                    if (Math.Abs(X[0] - L) <= 1.0e-8)
                    {
                        et = 4;
                    }

                    return(et);
                });

                return(grd);
            };


            //double L = 1; //lambda_instable;
            //double H = 1.0 * L;
            //double H_interf = L / 4.0;

            ////int xkelem = 20;
            //int ykelem_Interface = 1 * kelem / 2;
            //int ykelem_outer = kelem / 2;

            //C.GridFunc = delegate () {
            //    double[] xNodes = GenericBlas.Linspace(0, L, kelem + 1);
            //    //double[] Ynodes_Interface = GenericBlas.Linspace(-(H_interf) / 2.0, (H_interf) / 2.0, ykelem_Interface);
            //    //Ynodes_Interface = Ynodes_Interface.GetSubVector(1, Ynodes_Interface.GetLength(0) - 2);
            //    //double[] Ynodes_lower = GenericBlas.Linspace(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1);
            //    //double[] Ynodes_upper = GenericBlas.Linspace((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1);
            //    //double[] Ynodes = Ynodes_lower.Concat(Ynodes_Interface).ToArray().Concat(Ynodes_upper).ToArray();
            //    var _yNodes1 = Grid1D.TanhSpacing(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1, 1.5, false);
            //    _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
            //    var _yNodes2 = GenericBlas.Linspace(-H_interf / 2.0, H_interf / 2.0, ykelem_Interface);
            //    _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
            //    var _yNodes3 = Grid1D.TanhSpacing((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1, 1.5, true);
            //    var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);

            //    var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: true);

            //    grd.EdgeTagNames.Add(1, "wall_lower");
            //    grd.EdgeTagNames.Add(2, "wall_upper");


            //    grd.DefineEdgeTags(delegate (double[] X) {
            //        byte et = 0;
            //        if (Math.Abs(X[1] + ((H_interf / 2.0) + H)) <= 1.0e-8)
            //            et = 1;
            //        if (Math.Abs(X[1] - ((H_interf / 2.0) + H)) <= 1.0e-8)
            //            et = 2;
            //        if (Math.Abs(X[0]) <= 1.0e-8)
            //            et = 3;
            //        if (Math.Abs(X[0] - L) <= 1.0e-8)
            //            et = 4;

            //        return et;
            //    });

            //    return grd;
            //};

            #endregion


            // boundary conditions
            // ===================
            #region BC

            C.AddBoundaryValue("wall_lower");
            C.AddBoundaryValue("wall_upper");
            C.AddBoundaryValue("freeslip_left");
            C.AddBoundaryValue("freeslip_right");

            #endregion


            // Initial Values
            // ==============
            #region init

            //int k = 1;
            double A0 = 0.05;
            C.InitialValues_Evaluators.Add("Phi", (X => X[1] - (2.0 + A0 * Math.Cos(2.0 * Math.PI * X[0]))));

            C.InitialValues_Evaluators.Add("VelocityY#A", X => 0.0);
            C.InitialValues_Evaluators.Add("VelocityY#B", X => 0.0);

            double g = 1.0;
            C.InitialValues_Evaluators.Add("GravityY#A", X => - g);
            C.InitialValues_Evaluators.Add("GravityY#B", X => - g);

            //var database = new DatabaseInfo(_DbPath);
            //Guid restartID = new Guid("12b8c9f7-504c-40c4-a548-304a2e2aa14f");
            //C.RestartInfo = new Tuple<Guid, Foundation.IO.TimestepNumber>(restartID, 3420);

            #endregion


            // Physical Parameters
            // ===================
            #region physics

            //C.PhysicalParameters.rho_A = 0.17;
            //C.PhysicalParameters.rho_B = 1.2;
            //C.PhysicalParameters.mu_A = 0.17e-2;
            //C.PhysicalParameters.mu_B = 1.2e-2;
            //C.PhysicalParameters.Sigma = 0.0;

            C.PhysicalParameters.rho_A = 0.17;
            C.PhysicalParameters.rho_B = 1.2;
            C.PhysicalParameters.mu_A  = 0.003;
            C.PhysicalParameters.mu_B  = 0.003;
            C.PhysicalParameters.Sigma = 0.0;   // corresponding dt = 1e-3;
            //C.PhysicalParameters.Sigma = 0.015;   // corresponding dt = 4e-3;

            C.PhysicalParameters.IncludeConvection = true;
            C.PhysicalParameters.Material          = true;

            #endregion



            // additional parameters
            // =====================

            //double[] param = new double[4];
            //param[0] = k;   // wavenumber
            //param[1] = L;  // wavelength
            //param[2] = A0;      // initial disturbance
            //param[3] = g;      // y-gravity
            //C.AdditionalParameters = param;


            // misc. solver options
            // ====================
            #region solver


            //C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;
            //C.AdvancedDiscretizationOptions.PenaltySafety = 40;
            //C.AdvancedDiscretizationOptions.UseGhostPenalties = true;

            C.LSContiProjectionMethod       = ContinuityProjectionOption.SpecFEM;
            C.VelocityBlockPrecondMode      = MultigridOperator.Mode.SymPart_DiagBlockEquilib;
            C.Solver_MaxIterations          = 50;
            C.Solver_ConvergenceCriterion   = 1e-8;
            C.LevelSet_ConvergenceCriterion = 1e-6;

            C.LinearSolver = DirectSolver._whichSolver.MUMPS;

            C.AdvancedDiscretizationOptions.FilterConfiguration = CurvatureAlgorithms.FilterConfiguration.Default;
            C.AdvancedDiscretizationOptions.SST_isotropicMode   = Solution.XNSECommon.SurfaceStressTensor_IsotropicMode.Curvature_Projected;
            C.AdvancedDiscretizationOptions.FilterConfiguration.FilterCurvatureCycles = 1;

            #endregion


            // Timestepping
            // ============
            #region time

            C.CompMode = AppControl._CompMode.Transient;

            C.Timestepper_Scheme  = XNSE_Control.TimesteppingScheme.ImplicitEuler;
            C.Timestepper_BDFinit = TimeStepperInit.SingleInit;
            //C.dt_increment = 20;
            C.Timestepper_LevelSetHandling = LevelSetHandling.LieSplitting;

            double dt = 1e-3;
            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 1000;
            C.NoOfTimesteps = 4000;

            C.saveperiod = 4;

            #endregion

            return(C);
        }
Ejemplo n.º 25
0
        /// <summary>
        /// One Iteration of the ReInitialization
        /// Operators must be built first
        /// </summary>
        /// <param name="ChangeRate">
        /// L2-Norm of the Change-Rate in the level set in this reinit step
        /// </param>
        /// <param name="Restriction">
        /// The subgrid, on which the ReInit is performed
        /// </param>
        /// <param name="IncludingInterface">
        /// !! Not yet functional !!
        /// True, if the subgrid contains the interface, this causes all external edges of the subgrid to be treated as boundaries
        /// False, for the rest of the domain, thus the flux to the adjacent cells wil be evaluated
        /// </param>
        /// <returns></returns>
        public void ReInitSingleStep(out double ChangeRate, SubGrid Restriction = null, bool IncludingInterface = true)
        {
            if (!IncludingInterface)
            {
                throw new NotImplementedException("Untested, not yet functional!");
            }

            using (new FuncTrace()) {
                /// Init Residuals
                Residual.Clear();
                Residual.Acc(1.0, Phi);
                OldPhi.Clear();
                OldPhi.Acc(1.0, Phi);
                NewPhi.Clear();
                NewPhi.Acc(1.0, Phi);

                CellMask RestrictionMask = Restriction == null ? null : Restriction.VolumeMask;


                //if (Control.Upwinding && UpdateDirection && IterationCounter % 10 == 0) {

                if (false && Control.Upwinding && UpdateDirection)
                {
                    //if (Control.Upwinding && UpdateDirection) {
                    UpdateBulkMatrix(Restriction);
                }

                UpdateDirection = false;
                // RHS part
                RHSField.CoordinateVector.Clear();
                //Operator_RHS.Evaluate(NewPhi.Mapping, RHSField.Mapping);
                Operator_RHS.Evaluate(double.NaN, IncludingInterface ? Restriction : null, IncludingInterface ? SubGridBoundaryModes.BoundaryEdge : SubGridBoundaryModes.InnerEdge, ArrayTools.Cat(new DGField[] { Phi }, parameterFields, new DGField[] { RHSField }));
#if DEBUG
                RHSField.CheckForNanOrInf();
#endif
                // solve
                // =====
                double[] RHS = OpAffine.CloneAs();
                RHS.ScaleV(-1.0);
                RHS.AccV(1.0, RHSField.CoordinateVector);


                SolverResult Result;
                if (Restriction != null)
                {
                    SubRHS.Clear();
                    SubSolution.Clear();

                    SubRHS.AccV(1.0, RHS, default(int[]), SubVecIdx);
                    SubSolution.AccV(1.0, NewPhi.CoordinateVector, default(int[]), SubVecIdx);

                    Result = slv.Solve(SubSolution, SubRHS);

                    NewPhi.Clear(RestrictionMask);
                    NewPhi.CoordinateVector.AccV(1.0, SubSolution, SubVecIdx, default(int[]));
                }
                else
                {
                    Result = slv.Solve(NewPhi.CoordinateVector, RHS);
                }
#if Debug
                OpMatrix.SpMV(-1.0, NewPhi.CoordinateVector, 1.0, RHS);
                Console.WriteLine("LinearSolver: {0} Iterations, Converged={1}, Residual = {2} ", Result.NoOfIterations, Result.Converged, RHS.L2Norm());
#endif



                // Apply underrelaxation

                Phi.Clear(RestrictionMask);
                Phi.Acc(1 - underrelaxation, OldPhi, RestrictionMask);
                Phi.Acc(underrelaxation, NewPhi, RestrictionMask);
                Residual.Acc(-1.0, Phi, RestrictionMask);
                ChangeRate = Residual.L2Norm(RestrictionMask);


                //Calculate
                LevelSetGradient.Clear();
                LevelSetGradient.Gradient(1.0, Phi, RestrictionMask);
                //LevelSetGradient.GradientByFlux(1.0, Phi);
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient, RestrictionMask);

                if (Control.Upwinding)
                {
                    //RestrictionMask.GetBitMask();
                    for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++)
                    {
                        NewDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]);
                        //NewDirection[i] = MeanLevelSetGradient.CoordinateVector[i];
                        OldDirection[i] -= NewDirection[i];
                    }

                    double MaxDiff = OldDirection.L2Norm();
                    //if (MaxDiff > 1E-20 && IterationCounter % 10 == 0 ) {
                    //if (MaxDiff > 1E-20) {
                    //    Console.WriteLine("Direction Values differ by {0}", MaxDiff);
                    if (MaxDiff > 0.2)
                    {
                        //UpdateDirection = true;
                        //Console.WriteLine("Direction Values differ by {0} => Updating ReInit-Matrix", MaxDiff);
                    }
                    ;
                    //}

                    //Console.WriteLine("HACK!!! Updating Upwind Matrix everytime!");
                    //UpdateDirection = true;

                    // Reset Value
                    OldDirection.Clear();
                    OldDirection.AccV(1.0, NewDirection);
                }
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Control for various testing
        /// </summary>
        /// <param name="p"></param>
        /// <param name="xkelem"></param>
        /// <param name="dt"></param>
        /// <param name="t_end"></param>
        /// <param name="_DbPath"></param>
        /// <returns></returns>
        public static XNSE_Control RT(int p = 2, int xkelem = 16, string _DbPath = null)
        {
            XNSE_Control C = new XNSE_Control();

            // basic database options
            // ======================
            #region db

            _DbPath = @"D:\local\local_Testcase_databases\Testcase_RTinstability";
            //_DbPath = @"\\fdyprime\userspace\smuda\cluster\cluster_db";

            C.DbPath      = _DbPath;
            C.savetodb    = C.DbPath != null;
            C.ProjectName = "XNSE/RT-Instability";

            C.LogValues       = XNSE_Control.LoggingValues.Wavelike;
            C.WriteInterfaceP = true;

            #endregion

            // DG degrees
            // ==========
            #region degrees

            C.FieldOptions.Add("VelocityX", new FieldOpts()
            {
                Degree   = p,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("VelocityY", new FieldOpts()
            {
                Degree   = p,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Pressure", new FieldOpts()
            {
                Degree   = p - 1,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("GravityY", new FieldOpts()
            {
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("PhiDG", new FieldOpts()
            {
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Phi", new FieldOpts()
            {
                Degree   = p,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Curvature", new FieldOpts()
            {
                Degree   = p,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });

            #endregion


            // Physical Parameters
            // ===================
            #region physics


            // Capillary wave: Laplace number La = 3e5:
            //C.Tags.Add("La=3e5");
            //double rho_l = 1e-3;
            //double rho_h = 1e-3;
            //double mu_l = 1e-5;
            //double mu_h = 1e-5;
            //double sigma = 3e-2;

            // Capillary wave: Laplace number La = 3000:
            //C.Tags.Add("La3000");
            //double rho_l = 1e-3;
            //double rho_h = 1e-3;
            //double mu_l = 1e-4;
            //double mu_h = 1e-4;
            //double sigma = 3e-2;

            // Capillary wave: Laplace number La = 120:
            //double rho_l = 1e-3;
            //double rho_h = 1e-3;
            //double mu_l = 5e-4;
            //double mu_h = 5e-4;
            //double sigma = 3e-2;

            //double rho_l = 1e-3;
            //double rho_h = 1e-3;
            //double mu_l = 1e-6;
            //double mu_h = 1e-4;
            //double sigma = 3e-2;

            //double rho_l = 1;
            //double rho_h = 1;
            //double mu_l = 1e-3;
            //double mu_h = 1e-3;
            //double sigma = 1;

            // Air(light)-Water(heavy)
            //double rho_h = 1e-3;          // kg / cm^3
            //double rho_l = 1.2e-6;        // kg / cm^3
            //double mu_h = 1e-5;           // kg / cm * s
            //double mu_l = 17.1e-8;        // kg / cm * s
            //double sigma = 72.75e-3;      // kg / s^2         // lambda_crit = 1.7121 ; lambda < lambda_c: stable

            // same kinematic viscosities
            //double rho_l = 1e-5;          // kg / cm^3
            //double mu_l = 1e-8;           // kg / cm * s
            //double rho_h = 1e-3;        // kg / cm^3
            //double mu_h = 1e-6;        // kg / cm * s         // Atwood number = 0.98

            //double rho_l = 7e-4;          // kg / cm^3
            //double mu_l = 7e-5;           // kg / cm * s
            //double rho_h = 1e-3;        // kg / cm^3
            //double mu_h = 1e-4;        // kg / cm * s           // Atwood number = 0.1765

            //double sigma = 72.75e-3;      // kg / s^2


            //double rho_l = 1e-3;
            //double mu_l = 1e-4;
            //double rho_h = 1;
            //double mu_h = 1e-1;

            //double sigma = 100;      // kg / s^2

            double rho_l = 1e-1;
            double mu_l  = 1e-2;
            double rho_h = 10;
            double mu_h  = 1;

            double sigma = 50;      // kg / s^2

            // Water-Oil
            //double rho_ = 8.63e-4;
            //double rho_B = 1.2e-6;
            //double mu_A = 2e-4;
            //double mu_B = 17.1e-8;


            // stable configuration
            //C.PhysicalParameters.rho_A = rho_h;
            //C.PhysicalParameters.rho_B = rho_l;
            //C.PhysicalParameters.mu_A = mu_h;
            //C.PhysicalParameters.mu_B = mu_l;
            //C.PhysicalParameters.Sigma = sigma;


            // unstable configuration
            C.PhysicalParameters.rho_A = rho_l;
            C.PhysicalParameters.rho_B = rho_h;
            C.PhysicalParameters.mu_A  = mu_l;
            C.PhysicalParameters.mu_B  = mu_h;
            C.PhysicalParameters.Sigma = sigma;

            //C.PhysicalParameters.Sigma = 0.0;   // free surface boundary condition

            C.PhysicalParameters.IncludeConvection = true;
            C.PhysicalParameters.Material          = true;

            #endregion


            // Initial displacement
            // ===================

            int    kmode = 1;
            double H0    = 0.01;

            //double lambda_stable = 1;
            //double lambda_instable = 4;
            //Func<double, double> displacement = x => ((lambda_stable / 100) * Math.Sin(x * 2 * Math.PI / lambda_stable )) + ((lambda_instable / 100) * Math.Sin(x * 2 * Math.PI / lambda_instable));
            Func <double, double> displacement = x => (H0 * Math.Sin(x * 2 * Math.PI * (double)kmode));


            // grid genration
            // ==============
            #region grid

            double L        = 1; //lambda_instable;
            double H        = 1.0 * L;
            double H_interf = L / 4.0;

            //int xkelem = 20;
            int ykelem_Interface = 1 * xkelem;      // /2
            int ykelem_outer     = xkelem / 2;      // /2

            C.GridFunc = delegate() {
                double[] xNodes = GenericBlas.Linspace(0, L, xkelem + 1);
                //double[] Ynodes_Interface = GenericBlas.Linspace(-(H_interf) / 2.0, (H_interf) / 2.0, ykelem_Interface);
                //Ynodes_Interface = Ynodes_Interface.GetSubVector(1, Ynodes_Interface.GetLength(0) - 2);
                //double[] Ynodes_lower = GenericBlas.Linspace(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1);
                //double[] Ynodes_upper = GenericBlas.Linspace((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1);
                //double[] Ynodes = Ynodes_lower.Concat(Ynodes_Interface).ToArray().Concat(Ynodes_upper).ToArray();
                var _yNodes1 = Grid1D.TanhSpacing(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1, 1.5, false);
                _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                var _yNodes2 = GenericBlas.Linspace(-H_interf / 2.0, H_interf / 2.0, ykelem_Interface);
                _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                var _yNodes3 = Grid1D.TanhSpacing((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1, 1.5, true);
                var yNodes   = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);

                var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: true);

                grd.EdgeTagNames.Add(1, "wall_lower");
                grd.EdgeTagNames.Add(2, "wall_upper");


                grd.DefineEdgeTags(delegate(double[] X) {
                    byte et = 0;
                    if (Math.Abs(X[1] + ((H_interf / 2.0) + H)) <= 1.0e-8)
                    {
                        et = 1;
                    }
                    if (Math.Abs(X[1] - ((H_interf / 2.0) + H)) <= 1.0e-8)
                    {
                        et = 2;
                    }
                    if (Math.Abs(X[0]) <= 1.0e-8)
                    {
                        et = 3;
                    }
                    if (Math.Abs(X[0] - L) <= 1.0e-8)
                    {
                        et = 4;
                    }

                    return(et);
                });

                return(grd);
            };

            // nach Popinet
            //C.GridFunc = delegate () {
            //    double[] Xnodes = GenericBlas.Linspace(0, L, xkelem + 1);
            //    double[] Ynodes = GenericBlas.Linspace(-3.0 * L / 2.0, 3.0 * L / 2.0, (3 * xkelem) + 1);
            //    var grd = Grid2D.Cartesian2DGrid(Xnodes, Ynodes, periodicX: true);

            //    grd.EdgeTagNames.Add(1, "wall_lower");
            //    grd.EdgeTagNames.Add(2, "wall_upper");


            //    grd.DefineEdgeTags(delegate (double[] X) {
            //        byte et = 0;
            //        if (Math.Abs(X[1] + (3.0 * L / 2.0)) <= 1.0e-8)
            //            et = 1;
            //        if (Math.Abs(X[1] - (3.0 * L / 2.0)) <= 1.0e-8)
            //            et = 2;
            //        if (Math.Abs(X[0]) <= 1.0e-8)
            //            et = 3;
            //        if (Math.Abs(X[0] - L) <= 1.0e-8)
            //            et = 4;

            //        return et;
            //    });

            //    return grd;
            //};


            #endregion


            // boundary conditions
            // ===================
            #region BC

            C.AddBoundaryValue("wall_lower");
            C.AddBoundaryValue("wall_upper");

            #endregion


            // Initial Values
            // ==============
            #region init

            Func <double, double> PeriodicFunc = x => displacement(x);

            //superposed higher frequent disturbance
            //double lambda_dist = lambda / (double)(xkelem / 2);
            //if (lambda_dist > 0.0) {
            //    double A0_dist = A0 / 5.0;
            //    Func<double, double> disturbance = x => A0_dist * Math.Sin(x * 2 * Math.PI / lambda_dist);
            //    PeriodicFunc = x => (displacement(x) + disturbance(x));
            //}


            C.InitialValues_Evaluators.Add("Phi", (X => X[1] - (PeriodicFunc(X[0]))));

            C.InitialValues_Evaluators.Add("VelocityX#A", X => 0.0);
            C.InitialValues_Evaluators.Add("VelocityX#B", X => 0.0);

            double g = 9.81; // e2;
            C.InitialValues_Evaluators.Add("GravityY#A", X => - g);
            C.InitialValues_Evaluators.Add("GravityY#B", X => - g);

            //var database = new DatabaseInfo(_DbPath);
            //Guid restartID = new Guid("0141eba2-8d7b-4593-8595-bfff12dbfc40");
            //C.RestartInfo = new Tuple<Guid, Foundation.IO.TimestepNumber>(restartID, null);

            #endregion


            // misc. solver options
            // ====================
            #region solver


            //C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;
            //C.AdvancedDiscretizationOptions.PenaltySafety = 40;
            //C.AdvancedDiscretizationOptions.UseGhostPenalties = true;

            C.LSContiProjectionMethod       = ContinuityProjectionOption.SpecFEM;
            C.VelocityBlockPrecondMode      = MultigridOperator.Mode.SymPart_DiagBlockEquilib;
            C.NoOfMultigridLevels           = 1;
            C.Solver_MaxIterations          = 50;
            C.Solver_ConvergenceCriterion   = 1e-8;
            C.LevelSet_ConvergenceCriterion = 1e-6;

            C.LinearSolver = DirectSolver._whichSolver.MUMPS;

            //C.Option_LevelSetEvolution = LevelSetEvolution.Fourier;
            //C.AdvancedDiscretizationOptions.surfTensionMode = SurfaceTensionMode.Curvature_Fourier;

            C.AdvancedDiscretizationOptions.FilterConfiguration = CurvatureAlgorithms.FilterConfiguration.Default;
            C.AdvancedDiscretizationOptions.SST_isotropicMode   = Solution.XNSECommon.SurfaceStressTensor_IsotropicMode.Curvature_Projected;
            C.AdvancedDiscretizationOptions.FilterConfiguration.FilterCurvatureCycles = 1;

            #endregion


            // additional parameters
            // =====================

            double[] param = new double[4];
            param[0] = kmode; // wavenumber
            param[1] = L;     // wavelength
            param[2] = H0;    // initial disturbance
            param[3] = g;     // y-gravity
            C.AdditionalParameters = param;

            // specialized Fourier Level-Set
            // =============================

            //int numSp = 640;
            //C.FourierLevSetControl = new FourierLevSetControl(FourierType.Planar, numSp, L, PeriodicFunc, 1.0 / (double)xkelem) {
            //    FourierEvolve = Fourier_Evolution.MaterialPoints,
            //    Timestepper = FourierLevelSet_Timestepper.RungeKutta1901,
            //    InterpolationType = Interpolationtype.CubicSplineInterpolation
            //};


            // Timestepping
            // ============
            #region time

            C.CompMode = AppControl._CompMode.Transient;

            C.Timestepper_Scheme  = XNSE_Control.TimesteppingScheme.ImplicitEuler;
            C.Timestepper_BDFinit = TimeStepperInit.SingleInit;
            //C.dt_increment = 20;
            C.Timestepper_LevelSetHandling = LevelSetHandling.LieSplitting;

            double dt = 1e-4;
            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 1000;
            C.NoOfTimesteps = 4000;

            C.saveperiod = 4;

            #endregion


            return(C);
        }
Ejemplo n.º 27
0
        public static IBM_Control[] IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0)
        {
            List <IBM_Control> R = new List <IBM_Control>();

            foreach (int i in new int[] { 3 })
            {
                IBM_Control C = new IBM_Control();

                C.Paramstudy_CaseIdentification = new Tuple <string, object>[] {
                    new Tuple <string, object>("k", i),
                };

                k = i;

                const double BaseSize = 1.0;

                // basic database options
                // ======================

                C.DbPath      = @"\\fdyprime\userspace\krause\BoSSS_DBs\Paper_CellAgglo01_Penalty4";
                C.savetodb    = false;
                C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2";

                switch (i)
                {
                case 1:
                    C.MeshFactor = 1.33; // was 1.33
                    break;

                case 2:
                    C.MeshFactor = 0.92;
                    break;

                case 3:
                    C.MeshFactor = 0.7; // was 07
                    break;

                default:

                    throw new ApplicationException();
                }

                C.ProjectDescription = "Cylinder";
                C.Tags.Add("with immersed boundary method");

                // DG degrees
                // ==========

                C.FieldOptions.Add("VelocityX", new FieldOpts()
                {
                    Degree   = k,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                C.FieldOptions.Add("VelocityY", new FieldOpts()
                {
                    Degree   = k,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                //Console.WriteLine("Achtung: equal order!!!!");
                C.FieldOptions.Add("Pressure", new FieldOpts()
                {
                    Degree = k - 1,

                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                C.FieldOptions.Add("PhiDG", new FieldOpts()
                {
                    Degree   = 2,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });
                C.FieldOptions.Add("Phi", new FieldOpts()
                {
                    Degree   = 2,
                    SaveToDB = FieldOpts.SaveToDBOpt.TRUE
                });

                //grid and boundary conditions
                // ============================

                C.GridFunc = delegate {
                    var _xNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(10 * C.MeshFactor), 0.5, false); //10
                    _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1));
                    var _xNodes2 = GenericBlas.Linspace(-1, 2, Convert.ToInt32(35 * C.MeshFactor));            //35
                    _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1));
                    var _xNodes3 = Grid1D.TanhSpacing(2, 20, Convert.ToInt32(60 * C.MeshFactor), 1.5, true);   //60

                    var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3);


                    var _yNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(7 * C.MeshFactor), 0.9, false); //7
                    _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                    var _yNodes2 = GenericBlas.Linspace(-1, 1, Convert.ToInt32(25 * C.MeshFactor));           //25
                    _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                    var _yNodes3 = Grid1D.TanhSpacing(1, 2.1, Convert.ToInt32(7 * C.MeshFactor), 1.1, true);  //7
                    var yNodes   = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);



                    //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25);
                    //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25);
                    var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic);
                    grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                    grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                    if (!xPeriodic)
                    {
                        grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                        grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                    }

                    grd.DefineEdgeTags(delegate(double[] X) {
                        byte et = 0;
                        if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8)
                        {
                            et = 1;
                        }
                        if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
                        {
                            et = 2;
                        }
                        if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8)
                        {
                            et = 3;
                        }
                        if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
                        {
                            et = 4;
                        }


                        Debug.Assert(et != 0);
                        return(et);
                    });

                    Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

                    return(grd);
                };

                //C.GridFunc = delegate {

                //    // Box1
                //    var box1_p1 = new double[2] { -2, -2 };
                //    var box1_p2 = new double[2] { 20, 2.1 };
                //    var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15

                //    // Box2
                //    var box2_p1 = new double[2] { -2, -2 };
                //    var box2_p2 = new double[2] { 3, 2.1 };
                //    var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30

                //    // Box3
                //    var box3_p1 = new double[2] { -2, -1 };
                //    var box3_p2 = new double[2] { 1, 1 };
                //    var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58  ; k2: 32,38; k3: 24, 30

                //    // Box4
                //    var box4_p1 = new double[2] { -0.7, -0.72 };
                //    var box4_p2 = new double[2] { 0.7, 0.7 };
                //    var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84  ; k2: 30,56; k3: 22, 42

                //    var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4);

                //    grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                //    grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                //    if (!xPeriodic) {
                //        grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                //        grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                //    }

                //    grd.DefineEdgeTags(delegate (double[] X) {
                //        byte et = 0;
                //        if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8)
                //            et = 1;
                //        if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
                //            et = 2;
                //        if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8)
                //            et = 3;
                //        if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
                //            et = 4;


                //        Debug.Assert(et != 0);
                //        return et;
                //    });

                //    Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

                //    return grd;
                //};

                C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0);
                C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1))
                if (!xPeriodic)
                {
                    C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1)));
                    //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1);
                }
                C.AddBoundaryCondition("Pressure_Outlet_right");


                // Initial Values
                // ==============

                double radius = 0.5;
                C.PhysicalParameters.rho_A = 1;
                C.PhysicalParameters.mu_A  = 1.0 / 20;

                //C.InitialValues.Add("Phi", X => phi(X, 0));

                //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2()));  // quadratic form
                //    );
                C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2());
                //C.InitialValues.Add("Phi", X => -1);

                C.InitialValues_Evaluators.Add("VelocityX", X => 4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1));
                //C.InitialValues.Add("VelocityX", delegate (double[] X)
                //{
                //    double x = X[0];
                //    double y = X[1];

                //    double R = Math.Sqrt((x + 1).Pow2() + y.Pow2());

                //    double xVel = 0;

                //    if (R < 0.75)
                //    {
                //        xVel = 1;
                //    }
                //    return xVel;
                //});

                //C.InitialValues.Add("VelocityY", delegate (double[] X) {
                //    double x = X[0];
                //    double y = X[1];

                //    double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2());

                //    double yVel = 0;

                //    if (R < 0.75) {
                //        yVel = 1;
                //    }
                //    return yVel;
                //});

                // For restart
                //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95);
                //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f");

                // Physical Parameters
                // ===================


                C.PhysicalParameters.IncludeConvection = true;


                // misc. solver options
                // ====================

                C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;

                C.LevelSetSmoothing = false;
                //C.option_solver = "direct";
                C.MaxKrylovDim             = 20;
                C.MaxSolverIterations      = 50;
                C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;
                C.NoOfMultigridLevels      = 0;

                // Timestepping
                // ============

                C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.ImplicitEuler;
                double dt = 0.05;
                C.dtMax         = dt;
                C.dtMin         = dt;
                C.Endtime       = 70;
                C.NoOfTimesteps = 1000000;

                // haben fertig...
                // ===============

                R.Add(C);
            }

            return(R.ToArray());
        }
Ejemplo n.º 28
0
        private static int[] ComputeChangeOfBasisBlock(
            int[] BlockLen,
            MultidimensionalArray In_MassMatrixBlock, MultidimensionalArray In_OperatorMatrixBlock,
            MultidimensionalArray OUT_LeftPC, MultidimensionalArray OUT_rightPC, Mode PCMode, out int Rank,
            MultidimensionalArray work) //
        {
            Rank = In_MassMatrixBlock.NoOfCols;

            int[] IndefRows = null;

            switch (PCMode)
            {
            case Mode.Eye: {
                OUT_LeftPC.AccEye(1.0);
                OUT_rightPC.AccEye(1.0);
                break;
            }

            case Mode.DiagBlockEquilib: {
                double symmErr = In_OperatorMatrixBlock.SymmetryError();
                double infNorm = In_OperatorMatrixBlock.InfNorm();

                if (symmErr / infNorm > 1.0e-8)
                {
                    throw new ArithmeticException(string.Format("LDL_DiagBlock is not supported on unsymmetric matrices (Symm-Err: {0:0.####E-00}, Inf-Norm: {1:0.####E-00}, Quotient {2:0.####E-00}).", symmErr, infNorm, symmErr / infNorm));
                }
                SymmInv(In_OperatorMatrixBlock, OUT_LeftPC, OUT_rightPC);
                //In_OperatorMatrixBlock.SymmetricLDLInversion(OUT_rightPC, null);
                //OUT_rightPC.TransposeTo(OUT_LeftPC);
                break;
            }

            case Mode.SymPart_DiagBlockEquilib: {
                var SymmPart = work;
                In_OperatorMatrixBlock.TransposeTo(SymmPart);
                SymmPart.Acc(1.0, In_OperatorMatrixBlock);
                SymmPart.Scale(0.5);

                SymmInv(SymmPart, OUT_LeftPC, OUT_rightPC);
                break;
            }

            case Mode.IdMass: {
                In_MassMatrixBlock.SymmetricLDLInversion(OUT_rightPC, default(double[]));
                OUT_rightPC.TransposeTo(OUT_LeftPC);
                break;
            }

            case Mode.LeftInverse_DiagBlock: {
                In_OperatorMatrixBlock.InvertTo(OUT_LeftPC);
                OUT_rightPC.AccEye(1.0);
                break;
            }

            case Mode.LeftInverse_Mass: {
                In_MassMatrixBlock.InvertTo(OUT_LeftPC);
                OUT_rightPC.AccEye(1.0);
                break;
            }

            case Mode.IdMass_DropIndefinite: {
                int[] ZerosEntries = ModifiedInverseChol(In_MassMatrixBlock, OUT_rightPC, 1.0e-12, false);
                int   NoOfZeros    = ZerosEntries == null ? 0 : ZerosEntries.Length;
                IndefRows = ZerosEntries;
                Rank      = OUT_LeftPC.NoOfCols - NoOfZeros;
                OUT_rightPC.TransposeTo(OUT_LeftPC);
                break;
            }

            case Mode.SymPart_DiagBlockEquilib_DropIndefinite: {
                (Rank, IndefRows) = SymPart_DiagBlockEquilib_DropIndefinite(In_MassMatrixBlock, In_OperatorMatrixBlock, OUT_LeftPC, OUT_rightPC, work);

                break;
            }

            case Mode.SchurComplement: {
                //throw new NotImplementedException("todo");

                int NoVars = BlockLen.Length;
                if (NoVars <= 1)
                {
                    throw new NotSupportedException("The Schur complement requires at least 2 variables, moron!");
                }
                int N1 = BlockLen.Take(NoVars - 1).Sum();
                int N2 = BlockLen.Last();
                int N  = N1 + N2;

                //string TestPath = @"C:\Users\flori\OneDrive\MATLAB\Schur";
                //In_OperatorMatrixBlock.SaveToTextFile(Path.Combine(TestPath, "Opm.txt"));

                Debug.Assert(N == In_OperatorMatrixBlock.NoOfRows);
                Debug.Assert(N == In_OperatorMatrixBlock.NoOfCols);

                (MultidimensionalArray M11, MultidimensionalArray M12, MultidimensionalArray M21, MultidimensionalArray M22) GetSubblox(MultidimensionalArray Mtx)
                {
                    return(
                        Mtx.ExtractSubArrayShallow(new[] { 0, 0 }, new[] { N1 - 1, N1 - 1 }),
                        Mtx.ExtractSubArrayShallow(new[] { 0, N1 }, new[] { N1 - 1, N - 1 }),
                        Mtx.ExtractSubArrayShallow(new[] { N1, 0 }, new[] { N - 1, N1 - 1 }),
                        Mtx.ExtractSubArrayShallow(new[] { N1, N1 }, new[] { N - 1, N - 1 })
                        );
                }

                var OpMtxSub = GetSubblox(In_OperatorMatrixBlock);
                var MamaSub  = GetSubblox(In_MassMatrixBlock);
                var workSub  = GetSubblox(work);
                var lpcSub   = GetSubblox(OUT_LeftPC);
                var rpcSub   = GetSubblox(OUT_rightPC);

                (int Rank11, int[] IndefRows11) = SymPart_DiagBlockEquilib_DropIndefinite(MamaSub.M11, OpMtxSub.M11, lpcSub.M11, rpcSub.M11, workSub.M11);

                // compute lpcSub.M11*OpMtxSub.M11*rpcSub.M11
                // (without additional mem-alloc, yeah!)
                var Diag11 = workSub.M11;
                Diag11.GEMM(1.0, lpcSub.M11, OpMtxSub.M11, 0.0);
                OpMtxSub.M11.GEMM(1.0, Diag11, rpcSub.M11, 0.0);

                // invert diag
                if (Rank11 == N1)
                {
                    OpMtxSub.M11.InvertTo(workSub.M11);
                }
                else
                {
                    RankDefInvert(OpMtxSub.M11, workSub.M11);
                }

                //
                OpMtxSub.M11.GEMM(1.0, rpcSub.M11, OpMtxSub.M11, 0.0);
                workSub.M11.GEMM(1.0, OpMtxSub.M11, lpcSub.M11, 0.0);
                var Q = workSub.M11;

                //
                workSub.M21.GEMM(-1.0, OpMtxSub.M21, Q, 0.0);
                workSub.M12.GEMM(-1.0, Q, OpMtxSub.M12, 0.0);

                //rpcSub.M12.SetMatrix(workSub.M12); rpcSub.M22.AccEye(1.0);
                //lpcSub.M21.SetMatrix(workSub.M21); lpcSub.M22.AccEye(1.0);
                //OUT_LeftPC.SaveToTextFile(Path.Combine(TestPath, "Lpc.txt"));
                //OUT_rightPC.SaveToTextFile(Path.Combine(TestPath, "Rpc.txt"));


                rpcSub.M12.GEMM(1.0, Q, OpMtxSub.M12, 0.0);
                OpMtxSub.M22.GEMM(-1.0, OpMtxSub.M21, rpcSub.M12, 1.0);


                (int Rank22, int[] IndefRows22) = SymPart_DiagBlockEquilib_DropIndefinite(MamaSub.M22, OpMtxSub.M22, lpcSub.M22, rpcSub.M22, workSub.M22);

                lpcSub.M21.GEMM(1.0, lpcSub.M22, workSub.M21, 0.0);
                rpcSub.M12.GEMM(1.0, workSub.M12, rpcSub.M22, 0.0);

                //OUT_LeftPC.SaveToTextFile(Path.Combine(TestPath, "Lpc.txt"));
                //OUT_rightPC.SaveToTextFile(Path.Combine(TestPath, "Rpc.txt"));

                if (IndefRows11 != null && IndefRows22 != null)
                {
                    IndefRows = ArrayTools.Cat(IndefRows11, IndefRows22);
                }
                else if (IndefRows11 != null)
                {
                    IndefRows = IndefRows11;
                }
                else if (IndefRows22 != null)
                {
                    IndefRows = IndefRows22;
                }
                else
                {
                    IndefRows = null;
                }

                Rank = Rank11 + Rank22;
                break;
            }

            /*
             * case Mode.LDL_DiagBlock_DropIndefinite: {
             *      if(In_OperatorMatrixBlock.SymmetryError() / In_OperatorMatrixBlock.InfNorm() > 1.0e-8)
             *          throw new NotSupportedException("LDL_DiagBlock is not supported on unsymmetric matrices");
             *      int N = OUT_LeftPC.NoOfCols;
             *
             *      MultidimensionalArray PL = MultidimensionalArray.Create(N, N);
             *      MultidimensionalArray PR = MultidimensionalArray.Create(N, N);
             *
             *      int zeros1 = CRM114(In_MassMatrixBlock, PR, 1.0e-12);
             *      Rank = N - zeros1;
             *      PR.TransposeTo(PL);
             *
             *      var OpTr = (PL * In_OperatorMatrixBlock) * PR;
             *
             *      MultidimensionalArray QL = MultidimensionalArray.Create(N, N);
             *      MultidimensionalArray QR =  MultidimensionalArray.Create(N, N);
             *      int zeros2 = CRM114(OpTr, QR, 1.0e-12);
             *      QR.TransposeTo(QL);
             *
             *      if(zeros1 != zeros2)
             *          // I want this to fire also in Release mode, therfore i don't use Debug.Assert(...)
             *          throw new ApplicationException();
             *
             *
             *      OUT_LeftPC.GEMM(1.0, QL, PL, 0.0);
             *      OUT_rightPC.GEMM(1.0, PR, QR, 0.0);
             *
             *      //if (zeros1 > 0 || zeros2 > 0) {
             *      //    Console.WriteLine("zeros introduced: " + zeros1 + ", " + zeros2);
             *      //}
             *
             *      break;
             *  }
             */
            default:
                throw new NotImplementedException("Unknown option: " + PCMode);
            }

            return(IndefRows);
        }
Ejemplo n.º 29
0
        static public IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool only_channel = true, bool pardiso = true, int no_p = 1, int no_it = 1, bool load_Grid = false, string _GridGuid = null)
        {
            // int cells_x, int cells_yz
            IBM_Control  C         = new IBM_Control();
            bool         xPeriodic = false;
            int          i         = 2;
            const double BaseSize  = 1.0;

            // basic database options
            // ======================

            //C.DbPath = _DbPath;

            C.DbPath   = @"\\dc1\userspace\stange\HiWi_database\PerformanceTests";
            C.savetodb = true;

            bool   restart            = false;
            string restartSession     = "67a29dcc-ade9-4704-b198-b3380e774f5a";
            string restartGrid        = "42e1ede0-40fc-4267-9d48-94c0397ac9a5";
            bool   startFromGivenGrid = true;
            string startGrid          = "42e1ede0-40fc-4267-9d48-94c0397ac9a5";

            switch (i)
            {
            case 1:
                C.MeshFactor = 1.258;     // was 1.33
                break;

            case 2:
                C.MeshFactor = 3.0;     //1.77; //0.92;
                break;

            case 3:
                C.MeshFactor = 0.7;     // was 07
                break;

            default:

                throw new ApplicationException();
            }

            if (pardiso)
            {
                if (only_channel)
                {
                    C.SessionName = "2DChannel_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
                else
                {
                    C.SessionName = "Cylinder_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
            }
            else
            {
                if (only_channel)
                {
                    C.SessionName = "2DChannel_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
                else
                {
                    C.SessionName = "Cylinder_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it;
                }
            }
            C.saveperiod = 1;
            //C.SessionName = "Sphere_k" + k + "_h" + h+"Re100";


            C.Tags.Add("Pardiso " + pardiso);
            C.Tags.Add("only channel " + only_channel);
            C.Tags.Add("k " + k);
            C.Tags.Add("no_p" + no_p);
            C.Tags.Add("run " + no_it);
            C.Tags.Add("MeshFactor " + C.MeshFactor);

            C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2";

            C.ProjectDescription = "Cylinder";

            // DG degrees
            // ==========

            C.FieldOptions.Add("VelocityX", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("VelocityY", new FieldOpts()
            {
                Degree   = k,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            //Console.WriteLine("Achtung: equal order!!!!");
            C.FieldOptions.Add("Pressure", new FieldOpts()
            {
                Degree = k - 1,

                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("PhiDG", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });
            C.FieldOptions.Add("Phi", new FieldOpts()
            {
                Degree   = 2,
                SaveToDB = FieldOpts.SaveToDBOpt.TRUE
            });

            // restart options
            // ===============
            if (restart)
            {
                C.RestartInfo = new Tuple <Guid, TimestepNumber>(new Guid(restartSession), -1);
                C.GridGuid    = new Guid(restartGrid);
            }
            //grid and boundary conditions
            // ============================

            // Initial Values
            // ==============

            double radius = 0.5;

            C.PhysicalParameters.rho_A = 1.0;
            C.PhysicalParameters.mu_A  = 1.0 / 100.0;

            if (!restart)
            {
                if (!startFromGivenGrid)
                {
                    C.GridFunc = delegate
                    {
                        var _xNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(10.0 * C.MeshFactor), 0.5, false); //10
                        _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1));
                        var _xNodes2 = GenericBlas.Linspace(-1.0, 2.0, Convert.ToInt32(35.0 * C.MeshFactor));            //35
                        _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1));
                        var _xNodes3 = Grid1D.TanhSpacing(2.0, 20.0, Convert.ToInt32(60.0 * C.MeshFactor), 1.5, true);   //60

                        var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3);


                        var _yNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(7.0 * C.MeshFactor), 0.9, false); //7
                        _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1));
                        var _yNodes2 = GenericBlas.Linspace(-1.0, 1.0, Convert.ToInt32(25.0 * C.MeshFactor));           //25
                        _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1));
                        var _yNodes3 = Grid1D.TanhSpacing(1.0, 2.1, Convert.ToInt32(7.0 * C.MeshFactor), 1.1, true);    //7
                        var yNodes   = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3);



                        //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25);
                        //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25);
                        var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic);
                        grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
                        grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
                        if (!xPeriodic)
                        {
                            grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
                            grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
                        }

                        grd.DefineEdgeTags(delegate(double[] X)
                        {
                            byte et = 0;
                            if (Math.Abs(X[1] - (-2.0 * BaseSize)) <= 1.0e-8)
                            {
                                et = 1;
                            }
                            if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
                            {
                                et = 2;
                            }
                            if (!xPeriodic && Math.Abs(X[0] - (-2.0 * BaseSize)) <= 1.0e-8)
                            {
                                et = 3;
                            }
                            if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
                            {
                                et = 4;
                            }


                            Debug.Assert(et != 0);
                            return(et);
                        });

                        Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

                        return(grd);
                    };
                }
                else
                {
                    C.GridGuid = new Guid(startGrid);
                }
                if (only_channel)
                {
                    C.InitialValues_Evaluators.Add("Phi", X => - 1);
                }
                else
                {
                    C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2());
                }


                //C.InitialValues.Add("Phi", X => -1);

                C.InitialValues_Evaluators.Add("VelocityX", X => 4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1));
            }

            //C.GridFunc = delegate {

            //    // Box1
            //    var box1_p1 = new double[2] { -2, -2 };
            //    var box1_p2 = new double[2] { 20, 2.1 };
            //    var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15

            //    // Box2
            //    var box2_p1 = new double[2] { -2, -2 };
            //    var box2_p2 = new double[2] { 3, 2.1 };
            //    var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30

            //    // Box3
            //    var box3_p1 = new double[2] { -2, -1 };
            //    var box3_p2 = new double[2] { 1, 1 };
            //    var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58  ; k2: 32,38; k3: 24, 30

            //    // Box4
            //    var box4_p1 = new double[2] { -0.7, -0.72 };
            //    var box4_p2 = new double[2] { 0.7, 0.7 };
            //    var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84  ; k2: 30,56; k3: 22, 42

            //    var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4);

            //    grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper");
            //    grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower");
            //    if (!xPeriodic) {
            //        grd.EdgeTagNames.Add(3, "Velocity_Inlet_left");
            //        grd.EdgeTagNames.Add(4, "Pressure_Outlet_right");
            //    }

            //    grd.DefineEdgeTags(delegate (double[] X) {
            //        byte et = 0;
            //        if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8)
            //            et = 1;
            //        if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8)
            //            et = 2;
            //        if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8)
            //            et = 3;
            //        if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8)
            //            et = 4;


            //        Debug.Assert(et != 0);
            //        return et;
            //    });

            //    Console.WriteLine("Cells:    {0}", grd.NumberOfCells);

            //    return grd;
            //};

            C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0.0);
            C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0.0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1))
            if (!xPeriodic)
            {
                C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1)));
                //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1);
            }
            C.AddBoundaryCondition("Pressure_Outlet_right");



            //C.InitialValues.Add("Phi", X => phi(X, 0));

            //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2()));  // quadratic form
            //    );


            //C.InitialValues.Add("VelocityX", delegate (double[] X)
            //{
            //    double x = X[0];
            //    double y = X[1];

            //    double R = Math.Sqrt((x + 1).Pow2() + y.Pow2());

            //    double xVel = 0;

            //    if (R < 0.75)
            //    {
            //        xVel = 1;
            //    }
            //    return xVel;
            //});

            //C.InitialValues.Add("VelocityY", delegate (double[] X) {
            //    double x = X[0];
            //    double y = X[1];

            //    double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2());

            //    double yVel = 0;

            //    if (R < 0.75) {
            //        yVel = 1;
            //    }
            //    return yVel;
            //});

            // For restart
            //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95);
            //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f");

            // Physical Parameters
            // ===================


            C.PhysicalParameters.IncludeConvection = true;


            // misc. solver options
            // ====================

            C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2;
            C.AdvancedDiscretizationOptions.PenaltySafety = 4;
            C.LevelSetSmoothing = false;
            //C.option_solver = "direct";
            C.MaxKrylovDim             = 20;
            C.MaxSolverIterations      = 50;
            C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite;
            //C.NoOfMultigridLevels = 0;

            if (pardiso)
            {
                C.whichSolver = DirectSolver._whichSolver.PARDISO;
            }
            else
            {
                C.whichSolver = DirectSolver._whichSolver.MUMPS;
            }
            // Timestepping
            // ============

            C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2;
            double dt = 0.1;

            C.dtMax         = dt;
            C.dtMin         = dt;
            C.Endtime       = 70;
            C.NoOfTimesteps = 10;

            // haben fertig...
            // ===============
            return(C);
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Solution of the extension problem on a single cell in the far-region
        /// </summary>
        /// <param name="Phi">Input;</param>
        /// <param name="GradPhi">Input;</param>
        /// <param name="ExtProperty"></param>
        /// <param name="ExtPropertyMin">Input/Output: lower threshold.</param>
        /// <param name="ExtPropertyMax">Input/Output: upper threshold.</param>
        /// <param name="jCell"></param>
        /// <param name="Accepted"></param>
        /// <param name="signMod"></param>
        public void ExtVelSolve_Far(SinglePhaseField Phi, VectorField <SinglePhaseField> GradPhi, ConventionalDGField ExtProperty, ref double ExtPropertyMin, ref double ExtPropertyMax, int jCell, CellMask Accepted, double signMod)
        {
            GridData gDat = (GridData)(Phi.GridDat);

            Debug.Assert(signMod.Abs() == 1.0);
            Debug.Assert(ExtPropertyMin <= ExtPropertyMax);


            // define cell- and edge-mask for re-compute
            // =========================================

            CellMask cM = new CellMask(gDat, Chunk.GetSingleElementChunk(jCell));

            int[] Edges = gDat.iLogicalCells.Cells2Edges[jCell].CloneAs();
            for (int i = 0; i < Edges.Length; i++)
            {
                Edges[i] = Math.Abs(Edges[i]) - 1;
            }

            EdgeMask eM = new EdgeMask(gDat, FromIndEnum(Edges, gDat.iLogicalEdges.Count)); // won't scale.

            // solve the linear extension problem for 'jCell', eventually increase
            // diffusion until we are satisfied with the solution
            // ===================================================================

            bool   MaximumPrincipleFulfilled = false;
            double DiffusionCoeff = 0; // initially: try without diffusion
            double mini = double.NaN, maxi = double.NaN;
            int    count = 0;

            while (MaximumPrincipleFulfilled == false)  // as long as we are satisfied with the solution
            {
                count++;

                // compute operator in 'jCell'
                // ---------------------------

                int N   = ExtProperty.Basis.GetLength(jCell);
                int i0G = ExtProperty.Mapping.GlobalUniqueCoordinateIndex(0, jCell, 0);
                int i0L = ExtProperty.Mapping.GlobalUniqueCoordinateIndex(0, jCell, 0);

                for (int n = 0; n < N; n++)
                {
                    this.m_ExtvelMatrix.ClearRow(i0G + n);
                    this.m_ExtvelAffine[i0L + n] = 0;
                }

                double penaltyBase = ((double)(ExtProperty.Basis.Degree + 1)).Pow2();
                var    Flux        = new ExtensionVelocityForm(Accepted.GetBitMask(), signMod, penaltyBase, gDat.Cells.h_min, jCell, DiffusionCoeff);
                var    op          = (Flux).Operator(DegreeOfNonlinearity: 2);

                // increase diffusion coefficient for next cycle
                if (DiffusionCoeff == 0)
                {
                    DiffusionCoeff = 1.0e-3; // should this be minus or plus?
                }
                else
                {
                    DiffusionCoeff *= 10;
                }

                op.ComputeMatrixEx(ExtProperty.Mapping, ArrayTools.Cat <DGField>(new DGField[] { ExtProperty, Phi }, GradPhi), ExtProperty.Mapping,
                                   this.m_ExtvelMatrix, this.m_ExtvelAffine,
                                   OnlyAffine: false,
                                   volQuadScheme: (new CellQuadratureScheme(true, cM)),
                                   edgeQuadScheme: (new EdgeQuadratureScheme(true, eM)),
                                   ParameterMPIExchange: false);

                // extract operator matrix and RHS
                // -------------------------------

                // the matrix must only have entries in the block-diagonal!

                MultidimensionalArray Mtx = MultidimensionalArray.Create(N, N);
                //MultidimensionalArray rhs = MultidimensionalArray.Create(N);
                double[] rhs = new double[N];

                for (int n = 0; n < N; n++)
                {
#if DEBUG
                    int      Lr;
                    int[]    row_cols = null;
                    double[] row_vals = null;
                    Lr = this.m_ExtvelMatrix.GetRow(i0G + n, ref row_cols, ref row_vals);
                    for (int lr = 0; lr < Lr; lr++)
                    {
                        int    ColIndex = row_cols[lr];
                        double Value    = row_vals[lr];
                        Debug.Assert((ColIndex >= i0G && ColIndex < i0G + N) || (Value == 0.0), "Matrix is expected to be block-diagonal.");
                    }
#endif
                    for (int m = 0; m < N; m++)
                    {
                        Mtx[n, m] = this.m_ExtvelMatrix[i0G + n, i0G + m];
                    }
                    rhs[n] = -this.m_ExtvelAffine[i0L + n];
                }

                // Solve the system, i.e. the local extension-velocity equation
                // ------------------------------------------------------------

                double[] ep = new double[N];
                Mtx.Solve(ep, rhs);

                for (int n = 0; n < N; n++)
                {
                    ExtProperty.Coordinates[jCell, n] = ep[n];
                }

                // detect violation of maximum principle
                // -------------------------------------

                ExtProperty.GetExtremalValuesInCell(out mini, out maxi, jCell);

                // define relaxed bounds...
                double compExtPropertyMin = ExtPropertyMin - (1.0e-8 + ExtPropertyMax - ExtPropertyMin) * 0.2;
                double compExtPropertyMax = ExtPropertyMax + (1.0e-8 + ExtPropertyMax - ExtPropertyMin) * 0.2;

                // test if extension velocity solution is within bounds
                MaximumPrincipleFulfilled = (mini >= compExtPropertyMin) && (maxi <= compExtPropertyMax);

                if (count > 5)
                {
                    break;
                }
            }
            if (count > 4)
            {
                Console.WriteLine(" ExtVel, cell #{0}, Diff coeff {1}, extremal p. holds? {2} (min/max soll = {3:e4}/{4:e4}, ist = {5:e4}/{6:e4})", jCell, DiffusionCoeff, MaximumPrincipleFulfilled, ExtPropertyMin, ExtPropertyMax, mini, maxi);
            }

            // record maxima and minima
            // ========================
            ExtPropertyMax = Math.Max(ExtPropertyMax, maxi);
            ExtPropertyMin = Math.Min(ExtPropertyMin, mini);
        }