// 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); }
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); } }