/// <summary> /// Constructor /// </summary> /// <param name="gridData"></param> /// <param name="config"></param> public IBMFieldSet(IGridData gridData, IBMControl config) : base(gridData, config) { this.config = config; if (config.RestartInfo == null && !config.FieldOptions.ContainsKey(IBMVariables.LevelSet)) { throw new Exception( "Field 'levelSet' is required for IBM applications"); } LevelSet = new LevelSet( new Basis(gridData, config.FieldOptions[IBMVariables.LevelSet].Degree), IBMVariables.LevelSet); if (config.ContinuousLevelSet) { SpecFemBasis specFEMBasis = new SpecFemBasis((GridData)gridData, LevelSet.Basis.Degree); SpecFemField specFemField = new SpecFemField(specFEMBasis); specFemField.ProjectDGFieldMaximum(1.0, LevelSet); LevelSet.Clear(); specFemField.AccToDGField(1.0, LevelSet); } LevelSetGradient = new DGField[CompressibleEnvironment.NumberOfDimensions]; for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++) { LevelSetGradient[d] = DerivedFields[IBMVariables.LevelSetGradient[d]]; } }
private void CloseLevelSet() { rightTabControl.TabPages.Clear(); UpdateRightTabControlVisible(); _levelSet.Clear(); _fileName = string.Empty; }
/// <summary> /// Create Fields with same basis as DG Level Set /// </summary> protected override void CreateFields() { // create fields phi0 = new SinglePhaseField(DGLevSet.Basis, "phi0"); gradPhi0 = new VectorField <SinglePhaseField>(DGLevSet.GridDat.SpatialDimension.ForLoop(d => new SinglePhaseField(DGLevSet.Basis, "dPhiDG_dx[" + d + "]"))); Curvature = new SinglePhaseField(new Basis(phi0.GridDat, 0), VariableNames.Curvature); DCurvature = new SinglePhaseField(new Basis(phi0.GridDat, 0), "D" + VariableNames.Curvature); phi = new SinglePhaseField(DGLevSet.Basis, "phi"); phi.Acc(1.0, DGLevSet); mu = new SinglePhaseField(DGLevSet.Basis, "mu"); phi_Resi = new SinglePhaseField(DGLevSet.Basis, "phi_Resi"); mu_Resi = new SinglePhaseField(DGLevSet.Basis, "mu_Resi"); curvature_Resi = new SinglePhaseField(Curvature.Basis, "curvature_Resi"); // residuals: var solFields = InstantiateSolutionFields(); CurrentStateVector = new CoordinateVector(solFields); // residuals: var resFields = InstantiateResidualFields(); CurrentResidualVector = new CoordinateVector(resFields); //// Dummy Level Set //DummyLevSet = new LevelSet(new Basis(this.GridData, 1), "Levset"); //DummyLevSet.AccConstant(-1); //this.DummyLsTrk = new LevelSetTracker((GridData)(this.GridData), XQuadFactoryHelper.MomentFittingVariants.Saye, 1, new string[] { "A", "B" }, DummyLevSet); //this.DummyLsTrk.UpdateTracker(0.0); // Actual Level Set used for correction operations CorrectionLevSet = new LevelSet(phi.Basis, "Levset"); this.CorrectionLsTrk = new LevelSetTracker((GridData)(this.GridData), XQuadFactoryHelper.MomentFittingVariants.Saye, 2, new string[] { "A", "B" }, CorrectionLevSet); CorrectionLevSet.Clear(); CorrectionLevSet.Acc(1.0, phi); this.CorrectionLsTrk.UpdateTracker(0.0); // set coefficients SetCHCoefficents(); }
protected void MoveLevelSetTo(double time) { LevelSet levelSet = speciesMap.Tracker.LevelSets[0].As <LevelSet>(); levelSet.Clear(); levelSet.ProjectField(X => speciesMap.Control.LevelSetFunction(X, time)); speciesMap.Tracker.UpdateTracker(); cutCells = speciesMap.Tracker.Regions.GetCutCellMask(); cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells); // EVIL HACK SINCE UPDATE OF GRADIENT ONLY HAPPENS AFTER TIME-STEP SO FAR foreach (var gradientField in boundaryParameterMap.Fields) { int d = int.Parse(gradientField.Identification.Last().ToString()); gradientField.Clear(); gradientField.Derivative( -1.0, levelSet, d, cutCells); } }
public XDGTestSetup( int p, double AggregationThreshold, int TrackerWidth, MultigridOperator.Mode mumo, XQuadFactoryHelper.MomentFittingVariants momentFittingVariant, ScalarFunction LevSetFunc = null) { // Level set, tracker and XDG basis // ================================ if (LevSetFunc == null) { LevSetFunc = ((_2D)((x, y) => 0.8 * 0.8 - x * x - y * y)).Vectorize(); } LevSet = new LevelSet(new Basis(grid, 2), "LevelSet"); LevSet.Clear(); LevSet.ProjectField(LevSetFunc); LsTrk = new LevelSetTracker(grid, XQuadFactoryHelper.MomentFittingVariants.Classic, TrackerWidth, new string[] { "A", "B" }, LevSet); LsTrk.UpdateTracker(); XB = new XDGBasis(LsTrk, p); XSpatialOperator Dummy = new XSpatialOperator(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), "C1", "u"); //Dummy.EquationComponents["c1"].Add(new Dummy.Commit(); //Tecplot.PlotFields(new DGField[] { LevSet }, "agglo", 0.0, 3); // operator // ======== Debug.Assert(p <= 4); XDGBasis opXB = new XDGBasis(LsTrk, 4); // we want to have a very precise quad rule var map = new UnsetteledCoordinateMapping(opXB); int quadOrder = Dummy.QuadOrderFunction(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray()); //agg = new MultiphaseCellAgglomerator(new CutCellMetrics(momentFittingVariant, quadOrder, LsTrk, LsTrk.SpeciesIdS.ToArray()), AggregationThreshold, false); agg = LsTrk.GetAgglomerator(LsTrk.SpeciesIdS.ToArray(), quadOrder, __AgglomerationTreshold: AggregationThreshold); foreach (var S in LsTrk.SpeciesIdS) { Console.WriteLine("Species {0}, no. of agglomerated cells {1} ", LsTrk.GetSpeciesName(S), agg.GetAgglomerator(S).AggInfo.SourceCells.Count()); } // mass matrix factory // =================== // Basis maxB = map.BasisS.ElementAtMax(b => b.Degree); //MassFact = new MassMatrixFactory(maxB, agg); MassFact = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), quadOrder, 1).MassMatrixFactory; // Test field // ========== // set the test field: this is a polynomial function, // but different for each species; On this field, restriction followed by prolongation should be the identity this.Xdg_uTest = new XDGField(this.XB, "uTest"); Dictionary <SpeciesId, double> dumia = new Dictionary <SpeciesId, double>(); int i = 2; foreach (var Spc in LsTrk.SpeciesIdS) { dumia.Add(Spc, i); i -= 1; } SetTestValue(Xdg_uTest, dumia); // dummy operator matrix which fits polynomial degree p // ==================================================== Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping); Xdg_opMtx.AccEyeSp(120.0); // XDG Aggregation BasiseS // ======================= //XAggB = MgSeq.Select(agGrd => new XdgAggregationBasis[] { new XdgAggregationBasis(uTest.Basis, agGrd) }).ToArray(); XAggB = new XdgAggregationBasis[MgSeq.Length][]; var _XAggB = AggregationGridBasis.CreateSequence(MgSeq, Xdg_uTest.Mapping.BasisS); for (int iLevel = 0; iLevel < XAggB.Length; iLevel++) { XAggB[iLevel] = new[] { (XdgAggregationBasis)(_XAggB[iLevel][0]) }; XAggB[iLevel][0].Update(agg); } // Multigrid Operator // ================== Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping); Xdg_opMtx.AccEyeSp(120.0); XdgMultigridOp = new MultigridOperator(XAggB, Xdg_uTest.Mapping, Xdg_opMtx, MassFact.GetMassMatrix(Xdg_uTest.Mapping, false), new MultigridOperator.ChangeOfBasisConfig[][] { new MultigridOperator.ChangeOfBasisConfig[] { new MultigridOperator.ChangeOfBasisConfig() { VarIndex = new int[] { 0 }, mode = mumo, Degree = p } } }); }
/// <summary> /// Obtaining the time integrated spatial discretization of the reinitialization equation in a narrow band around the zero level set, based on a Godunov's numerical Hamiltonian calculation /// </summary> /// <param name="LS"> The level set function </param> /// <param name="Restriction"> The narrow band around the zero level set </param> /// <param name="NumberOfTimesteps"> /// maximum number of pseudo-timesteps /// </param> /// <param name="thickness"> /// The smoothing width of the signum function. /// This is the main stabilization parameter for re-initialization. /// It should be set to approximately 3 cells. /// </param> /// <param name="TimestepSize"> /// size of the pseudo-timestep /// </param> public void ReInitialize(LevelSet LS, SubGrid Restriction, double thickness, double TimestepSize, int NumberOfTimesteps) { using (var tr = new FuncTrace()) { // log parameters: tr.Info("thickness: " + thickness.ToString(NumberFormatInfo.InvariantInfo)); tr.Info("TimestepSize: " + TimestepSize.ToString(NumberFormatInfo.InvariantInfo)); tr.Info("NumberOfTimesteps: " + NumberOfTimesteps); ExplicitEuler TimeIntegrator; SpatialOperator SO; Func <int[], int[], int[], int> QuadratureOrder = QuadOrderFunc.NonLinear(3); if (m_ctx.SpatialDimension == 2) { SO = new SpatialOperator(1, 5, 1, QuadratureOrder, new string[] { "LS", "LSCGV", "LSDG[0]", "LSUG[0]", "LSDG[1]", "LSUG[1]", "Result" }); SO.EquationComponents["Result"].Add(new GodunovHamiltonian(m_ctx, thickness)); SO.Commit(); TimeIntegrator = new RungeKutta(m_Scheme, SO, new CoordinateMapping(LS), new CoordinateMapping(LSCGV, LSDG[0], LSUG[0], LSDG[1], LSUG[1]), sgrd: Restriction); } else { SO = new SpatialOperator(1, 7, 1, QuadratureOrder, new string[] { "LS", "LSCGV", "LSDG[0]", "LSUG[0]", "LSDG[1]", "LSUG[1]", "LSDG[2]", "LSUG[2]", "Result" }); SO.EquationComponents["Result"].Add(new GodunovHamiltonian(m_ctx, thickness)); SO.Commit(); TimeIntegrator = new RungeKutta(m_Scheme, SO, new CoordinateMapping(LS), new CoordinateMapping(LSCGV, LSDG[0], LSUG[0], LSDG[1], LSUG[1], LSDG[2], LSUG[2]), sgrd: Restriction); } // Calculating the gradients in each sub-stage of a Runge-Kutta integration procedure ExplicitEuler.ChangeRateCallback EvalGradients = delegate(double t1, double t2) { LSUG.Clear(); CalculateLevelSetGradient(LS, LSUG, "Upwind", Restriction); LSDG.Clear(); CalculateLevelSetGradient(LS, LSDG, "Downwind", Restriction); LSCG.Clear(); CalculateLevelSetGradient(LS, LSCG, "Central", Restriction); LSCGV.Clear(); var VolMask = (Restriction != null) ? Restriction.VolumeMask : null; LSCGV.ProjectAbs(1.0, VolMask, LSCG.ToArray()); }; TimeIntegrator.OnBeforeComputeChangeRate += EvalGradients; { EvalGradients(0, 0); var GodunovResi = new SinglePhaseField(LS.Basis, "Residual"); SO.Evaluate(1.0, 0.0, LS.Mapping, TimeIntegrator.ParameterMapping.Fields, GodunovResi.Mapping, Restriction); //Tecplot.Tecplot.PlotFields(ArrayTools.Cat<DGField>( LSUG, LSDG, LS, GodunovResi), "Residual", 0, 3); } // pseudo-timestepping // =================== double factor = 1.0; double time = 0; LevelSet prevLevSet = new LevelSet(LS.Basis, "prevLevSet"); CellMask RestrictionMask = (Restriction == null) ? null : Restriction.VolumeMask; for (int i = 0; (i < NumberOfTimesteps); i++) { tr.Info("Level set reinitialization pseudo-timestepping, timestep " + i); // backup old Levelset // ------------------- prevLevSet.Clear(); prevLevSet.Acc(1.0, LS, RestrictionMask); // time integration // ---------------- double dt = TimestepSize * factor; tr.Info("dt = " + dt.ToString(NumberFormatInfo.InvariantInfo) + " (factor = " + factor.ToString(NumberFormatInfo.InvariantInfo) + ")"); TimeIntegrator.Perform(dt); time += dt; // change norm // ------ prevLevSet.Acc(-1.0, LS, RestrictionMask); double ChangeNorm = prevLevSet.L2Norm(RestrictionMask); Console.WriteLine("Reinit: PseudoTime: {0} - Changenorm: {1}", i, ChangeNorm); //Tecplot.Tecplot.PlotFields(new SinglePhaseField[] { LS }, m_ctx, "Reinit-" + i, "Reinit-" + i, i, 3); } //*/ } }