Ejemplo n.º 1
0
        // Reinitialize Phasefield with changed interface thickness
        private void ReInit(double cahn_old, double cahn)
        {
            Console.WriteLine($"Reprojecting Phasefield:\n" +
                              $"  old thickness:  {cahn_old}\n" +
                              $"  new thickness:  {cahn}");
            // we assume the current phasefield is close to the equilibrium tangenshyperbolicus form
            SinglePhaseField phiNew  = new SinglePhaseField(phi.Basis);
            GridData         GridDat = (GridData)(phi.GridDat);

            // compute and project
            // step one calculate distance field phiDist = 0.5 * log(Max(1+phi, eps)/Max(1-phi, eps)) * sqrt(2) * Cahn_old
            // step two project the new phasefield phiNew = tanh(phiDist/(sqrt(2) * Cahn_new))
            // here done in one step, with default quadscheme
            // ===================
            phiNew.ProjectField(
                (ScalarFunctionEx) delegate(int j0, int Len, NodeSet NS, MultidimensionalArray result)
            {     // ScalarFunction2
                Debug.Assert(result.Dimension == 2);
                Debug.Assert(Len == result.GetLength(0));
                int K = result.GetLength(1);     // number of nodes

                // evaluate Phi
                // -----------------------------
                phi.Evaluate(j0, Len, NS, result);

                // compute the pointwise values of the new level set
                // -----------------------------

                result.ApplyAll(x => Math.Tanh(0.5 * Math.Log(Math.Max(1 + x, 1e-10) / Math.Max(1 - x, 1e-10)) * (cahn_old / cahn)));
            }
                );

            phi.Clear();
            phi.Acc(1.0, phiNew);

            CorrectionLevSet.Clear();
            CorrectionLevSet.Acc(1.0, phi);
            this.CorrectionLsTrk.UpdateTracker(0.0);

            // update DG LevelSet
            DGLevSet.Clear();
            DGLevSet.Acc(1.0, phi);

            reinit++;
            PlotCurrentState(0.0, reinit);
        }
Ejemplo n.º 2
0
        protected override double RunSolverOneStep(int _TimestepNo, double _dt, double _phystime)
        {
            using (new FuncTrace())
            {
                if (_TimestepNo == -1.0)
                {
                    Console.WriteLine("Initializing Phasefield");
                }
                else
                {
                    Console.WriteLine("Moving Phasefield in timestep #{0}, t = {1}, dt = {2} ...", _TimestepNo, _phystime, _dt);
                }

                // Perform timestep
                // ================

                if (this.Control.CurvatureCorrectionType == PhasefieldControl.CurvatureCorrection.DirectCoupledOnce)
                {
                    phi0.Clear();
                    phi0.Acc(1.0, phi);
                    gradPhi0.Clear();
                    gradPhi0.Gradient(1.0, phi0);

                    VectorField <SinglePhaseField> filtgrad;
                    CurvatureAlgorithmsForLevelSet.CurvatureDriver(
                        CurvatureAlgorithmsForLevelSet.SurfaceStressTensor_IsotropicMode.Curvature_Projected,
                        CurvatureAlgorithmsForLevelSet.FilterConfiguration.Phasefield,
                        this.DCurvature, out filtgrad, CorrectionLsTrk,
                        this.DCurvature.Basis.Degree * 2,
                        phi0);
                }

                //PlotCurrentState(_phystime, new Foundation.IO.TimestepNumber(new int[] { _TimestepNo , 0}), 2);
                base.Timestepping.Solve(_phystime, _dt);
                //PlotCurrentState(_phystime, new Foundation.IO.TimestepNumber(new int[] { _TimestepNo }), 2);

                // algebraic correction
                switch (this.Control.CorrectionType)
                {
                case PhasefieldControl.Correction.Concentration:
                    ConservativityCorrection();
                    break;

                case PhasefieldControl.Correction.Mass:
                    MassCorrection();
                    break;

                case PhasefieldControl.Correction.None:
                default:
                    break;
                }

                // update DG LevelSet
                DGLevSet.Clear();
                DGLevSet.Acc(1.0, phi);

                CorrectionLevSet.Clear();
                CorrectionLevSet.Acc(1.0, phi);
                this.CorrectionLsTrk.UpdateTracker(0.0);

                // return
                // ======
                WriteLogLine(_TimestepNo, _phystime + _dt);

                //PlotCurrentState(_phystime, new Foundation.IO.TimestepNumber(new int[] { _TimestepNo }), 2);

                Console.WriteLine("done moving Phasefield in timestep #{0}.", _TimestepNo);

                return(_dt);
            }
        }