public bool TryNewClustering(double dt) { bool reclustered = false; if (ABevolver[0].HistoryChangeRate.Count >= order - 1) { if (adaptive) { if (TimeInfo.TimeStepNumber % reclusteringInterval == 0) { // Fix for update problem of artificial viscosity RaiseOnBeforeComputechangeRate(Time, dt); //#if DEBUG Console.WriteLine("\n-------------------------------------------------------------------------------------------"); Console.WriteLine("### BUILD NEW CLUSTERING FOR TESTING ###"); //#endif // Necessary in order to use the number of sub-grids specified by the user for the reclustering in each time step // Otherwise the value could be changed by the constructor of the parent class (AdamsBashforthLTS.cs) --> CreateSubGrids() Clusterer.Clustering newClustering = clusterer.CreateClustering(numberOfClustersInitial, this.TimeStepConstraints, this.SubGrid); newClustering = clusterer.TuneClustering(newClustering, Time, this.TimeStepConstraints); // Might remove sub-grids when their time step sizes are too similar reclustered = clusterer.CheckForNewClustering(CurrentClustering, newClustering); //#if DEBUG //Console.WriteLine("########################################"); Console.WriteLine("-------------------------------------------------------------------------------------------"); //#endif // After the intitial phase, activate adaptive mode for all ABevolve objects foreach (ABevolve abE in ABevolver) { abE.adaptive = true; } if (reclustered) { Console.WriteLine("### RECLUSTERING ###"); CurrentClustering = newClustering; ShortenHistories(ABevolver); ABevolve[] oldABevolver = ABevolver; CreateNewABevolver(); CopyHistoriesOfABevolver(oldABevolver); } GetBoundaryTopology(); } } } return(reclustered); }
public IBMAdamsBashforthLTS(SpatialOperator standardOperator, SpatialOperator boundaryOperator, CoordinateMapping fieldsMap, CoordinateMapping boundaryParameterMap, ISpeciesMap ibmSpeciesMap, IBMControl control, IList <TimeStepConstraint> timeStepConstraints, int reclusteringInterval, bool fluxCorrection, bool forceReclustering, int maxNumOfSubSteps = 0, bool logging = false, bool consoleOutput = false) : base(standardOperator, fieldsMap, boundaryParameterMap, control.ExplicitOrder, control.NumberOfSubGrids, true, timeStepConstraints, reclusteringInterval: reclusteringInterval, fluxCorrection: fluxCorrection, subGrid: ibmSpeciesMap.SubGrid, forceReclustering: forceReclustering, logging: logging, consoleOutput: consoleOutput) { this.speciesMap = ibmSpeciesMap as ImmersedSpeciesMap; if (this.speciesMap == null) { throw new ArgumentException( "Only supported for species maps of type 'ImmersedSpeciesMap'", "speciesMap"); } this.standardOperator = standardOperator; this.boundaryOperator = boundaryOperator; this.boundaryParameterMap = boundaryParameterMap; this.fieldsMap = fieldsMap; this.control = control; agglomerationPatternHasChanged = true; cutCells = speciesMap.Tracker.Regions.GetCutCellMask(); cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells); if (consoleOutput) { Console.WriteLine("### This is IBM ABLTS ctor ###"); } // Normal LTS constructor clusterer = new Clusterer(this.gridData, maxNumOfSubSteps, cellAgglomerator: speciesMap.Agglomerator); CurrentClustering = clusterer.CreateClustering(control.NumberOfSubGrids, this.TimeStepConstraints, speciesMap.SubGrid); CurrentClustering = clusterer.TuneClustering(CurrentClustering, Time, this.TimeStepConstraints); // Might remove sub-grids when time step sizes are too similar ABevolver = new IBMABevolve[CurrentClustering.NumberOfClusters]; for (int i = 0; i < ABevolver.Length; i++) { ABevolver[i] = new IBMABevolve(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, control.ExplicitOrder, control.LevelSetQuadratureOrder, control.CutCellQuadratureType, sgrd: CurrentClustering.Clusters[i], adaptive: this.adaptive); ABevolver[i].OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); } GetBoundaryTopology(); // Start-up phase needs an IBM Runge-Kutta time stepper RungeKuttaScheme = new IBMSplitRungeKutta(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, timeStepConstraints); }
////################# Hack for saving to database in every (A)LTS sub-step //private Action<TimestepNumber, double> saveToDBCallback; ////################# Hack for saving to database in every (A)LTS sub-step /// <summary> /// Standard constructor for the (adaptive) local time stepping algorithm /// </summary> /// <param name="spatialOp">Spatial operator</param> /// <param name="Fieldsmap">Coordinate mapping for the variable fields</param> /// <param name="Parameters">optional parameter fields, can be null if <paramref name="spatialOp"/> contains no parameters; must match the parameter field list of <paramref name="spatialOp"/>, see <see cref="BoSSS.Foundation.SpatialOperator.ParameterVar"/></param> /// <param name="order">LTS/AB order</param> /// <param name="numOfClusters">Amount of sub-grids/clusters to be used for LTS</param> /// <param name="timeStepConstraints">Time step constraints for later usage as metric</param> /// <param name="subGrid">Sub-grids, e.g., from previous time steps</param> /// <param name="fluxCorrection">Bool for triggering the fluss correction</param> /// <param name="reclusteringInterval">Interval for potential reclustering</param> /// <param name="saveToDBCallback">Hack for plotting all sub-steps</param> /// <remarks>Uses the k-Mean clustering, see <see cref="BoSSS.Solution.Utils.Kmeans"/>, to generate the element groups</remarks> public AdamsBashforthLTS(SpatialOperator spatialOp, CoordinateMapping Fieldsmap, CoordinateMapping Parameters, int order, int numOfClusters, IList <TimeStepConstraint> timeStepConstraints = null, SubGrid subGrid = null, bool fluxCorrection = true, int reclusteringInterval = 0, Action <TimestepNumber, double> saveToDBCallback = null, int maxNumOfSubSteps = 0, bool forceReclustering = false, bool logging = false, bool consoleOutput = false) : base(spatialOp, Fieldsmap, Parameters, order, timeStepConstraints, subGrid) { this.forceReclustering = forceReclustering; this.Logging = logging; this.ConsoleOutput = consoleOutput; if (reclusteringInterval != 0) { NumberOfClustersInitial = numOfClusters; this.adaptive = true; } // Add OnBeforeComputeChangeRate (AV) to start-up phase time stepper RungeKuttaScheme.OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); this.reclusteringInterval = reclusteringInterval; this.gridData = Fieldsmap.Fields.First().GridDat; this.fluxCorrection = fluxCorrection; if (ConsoleOutput) { Console.WriteLine("### This is ABLTS ctor ###"); } clusterer = new Clusterer(this.gridData, maxNumOfSubSteps); CurrentClustering = clusterer.CreateClustering(numOfClusters, this.TimeStepConstraints, this.SubGrid); // Might remove clusters when their centres are too close CurrentClustering = clusterer.TuneClustering(CurrentClustering, Time, this.TimeStepConstraints); // Might remove clusters when their time step sizes are too similar ABevolver = new ABevolve[CurrentClustering.NumberOfClusters]; for (int i = 0; i < ABevolver.Length; i++) { ABevolver[i] = new ABevolve(spatialOp, Fieldsmap, Parameters, order, adaptive: this.adaptive, sgrd: CurrentClustering.Clusters[i]); ABevolver[i].OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2); } GetBoundaryTopology(); // Saving time steps in subgrids //this.saveToDBCallback = saveToDBCallback; }