/// <summary> /// All cells belonging to the same LTS cluster (clusters 0..n) are /// assigned to the same performance class. The cluster performing the /// largest time-steps corresponds to performance class 0, the cluster with /// the smallest time-steps to performance class n. /// </summary> /// <param name="program"></param> /// <returns></returns> public (int noOfClasses, int[] cellToPerformanceClassMap) ClassifyCells(IProgram <CNSControl> program) { AdamsBashforthLTS ltsTimeStepper = program.TimeStepper as AdamsBashforthLTS; if (ltsTimeStepper == null) { throw new Exception("LTS cell classifier is only sensible for LTS runs."); } int noOfClasses = ltsTimeStepper.CurrentClustering.NumberOfClusters; int[] cellToPerformanceClassMap = new int[program.Grid.NoOfUpdateCells]; for (int i = 0; i < ltsTimeStepper.CurrentClustering.NumberOfClusters; i++) { foreach (Chunk chunk in ltsTimeStepper.CurrentClustering.Clusters[i].VolumeMask) { foreach (int cell in chunk.Elements) { cellToPerformanceClassMap[cell] = i; } } } return(noOfClasses, cellToPerformanceClassMap); }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { SpatialOperator diffOp = new SpatialOperator(1, 0, 1, QuadOrderFunc.MaxDegTimesTwo(), "u", "codom1"); diffOp.EquationComponents["codom1"].Add(new ScalarTransportFlux()); diffOp.Commit(); CustomTimestepConstraint = new SurrogateConstraint(GridData, dt_input, dt_input, double.MaxValue, endTime); if (LTS) { AdamsBashforthLTS ltsTimeStepper = new AdamsBashforthLTS( diffOp, new CoordinateMapping(u), null, ABorder, numOfSubgrids, fluxCorrection: true, reclusteringInterval: 0, timeStepConstraints: new List <TimeStepConstraint>() { CustomTimestepConstraint }); timeStepper = ltsTimeStepper; } else if (ALTS) { AdamsBashforthLTS ltsTimeStepper = new AdamsBashforthLTS( diffOp, new CoordinateMapping(u), null, ABorder, numOfSubgrids, fluxCorrection: false, reclusteringInterval: 1, timeStepConstraints: new List <TimeStepConstraint>() { CustomTimestepConstraint }); timeStepper = ltsTimeStepper; } else { timeStepper = new AdamsBashforth(diffOp, new CoordinateMapping(u), null, ABorder); //timeStepper = new RungeKutta(RungeKutta.RungeKuttaScheme.Heun, diffOp, new CoordinateMapping(u),null); //timeStepper = RungeKutta.Factory(ABorder, diffOp, new CoordinateMapping(u)); } }
/// <summary> /// Creates the appropriate time-stepper for a given /// <paramref name="timeStepperType"/> /// </summary> /// <param name="timeStepperType"> /// The type of the time-stepper (e.g., Runge-Kutta) to be created /// </param> /// <param name="control"> /// Configuration options /// </param> /// <param name="equationSystem"> /// The equation system to be solved /// </param> /// <param name="fieldSet"> /// Fields affected by the time-stepper /// </param> /// <param name="parameterMap"> /// Fields serving as parameter for the time-stepper. /// </param> /// <param name="speciesMap"> /// Mapping of different species inside the domain /// </param> /// <param name="program"></param> /// <returns> /// Depending on <paramref name="timeStepperType"/>, an appropriate /// implementation of <see cref="ITimeStepper"/>. /// </returns> /// <remarks> /// Currently limiting is not supported for Adams-Bashforth methods /// </remarks> public static ITimeStepper Instantiate <T>( this ExplicitSchemes timeStepperType, CNSControl control, OperatorFactory equationSystem, CNSFieldSet fieldSet, CoordinateMapping parameterMap, ISpeciesMap speciesMap, IProgram <T> program) where T : CNSControl, new() { CoordinateMapping variableMap = new CoordinateMapping(fieldSet.ConservativeVariables); IBMControl ibmControl = control as IBMControl; IBMOperatorFactory ibmFactory = equationSystem as IBMOperatorFactory; if (control.DomainType != DomainTypes.Standard && (ibmFactory == null || ibmControl == null)) { throw new Exception(); } ITimeStepper timeStepper; switch (timeStepperType) { case ExplicitSchemes.RungeKutta when control.DomainType == DomainTypes.Standard: timeStepper = new RungeKutta( RungeKutta.GetDefaultScheme(control.ExplicitOrder), equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.RungeKutta: timeStepper = ibmControl.TimesteppingStrategy.CreateRungeKuttaTimeStepper( ibmControl, equationSystem, fieldSet, parameterMap, speciesMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.AdamsBashforth when control.DomainType == DomainTypes.Standard: timeStepper = new AdamsBashforth( equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, control.ExplicitOrder, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.AdamsBashforth: timeStepper = new IBMAdamsBashforth( ibmFactory.GetJoinedOperator().ToSpatialOperator(fieldSet), ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, speciesMap, ibmControl, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.LTS when control.DomainType == DomainTypes.Standard: timeStepper = new AdamsBashforthLTS( equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, control.ExplicitOrder, control.NumberOfSubGrids, equationSystem.GetJoinedOperator().CFLConstraints, reclusteringInterval: control.ReclusteringInterval, fluxCorrection: control.FluxCorrection, saveToDBCallback: program.SaveToDatabase, maxNumOfSubSteps: control.maxNumOfSubSteps, forceReclustering: control.forceReclustering, logging: control.WriteLTSLog, consoleOutput: control.WriteLTSConsoleOutput); break; case ExplicitSchemes.LTS: timeStepper = new IBMAdamsBashforthLTS( equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, speciesMap, ibmControl, equationSystem.GetJoinedOperator().CFLConstraints, reclusteringInterval: control.ReclusteringInterval, fluxCorrection: control.FluxCorrection, maxNumOfSubSteps: control.maxNumOfSubSteps, forceReclustering: control.forceReclustering, logging: control.WriteLTSLog, consoleOutput: control.WriteLTSConsoleOutput); break; case ExplicitSchemes.Rock4 when control.DomainType == DomainTypes.Standard: timeStepper = new ROCK4(equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), new CoordinateVector(variableMap), null); break; case ExplicitSchemes.SSP54 when control.DomainType == DomainTypes.Standard: timeStepper = new RungeKutta( RungeKuttaScheme.SSP54, equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.RKC84 when control.DomainType == DomainTypes.Standard: timeStepper = new RungeKutta( RungeKuttaScheme.RKC84, equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.None: throw new System.ArgumentException("Cannot instantiate empty scheme"); default: throw new NotImplementedException(String.Format( "Explicit time stepper type '{0}' not implemented for domain type '{1}'", timeStepperType, control.DomainType)); } // Make sure shock sensor is updated before every flux evaluation if (control.CNSShockSensor != null) { ExplicitEuler explicitEulerBasedTimestepper = timeStepper as ExplicitEuler; if (explicitEulerBasedTimestepper == null) { throw new Exception(String.Format( "Shock-capturing currently not implemented for time-steppers of type '{0}'", timeStepperType)); } explicitEulerBasedTimestepper.OnBeforeComputeChangeRate += delegate(double absTime, double relTime) { // Note: Only shock sensor is updated, _NOT_ the corresponding variable program.Control.CNSShockSensor.UpdateSensorValues( program.WorkingSet.AllFields, program.SpeciesMap, explicitEulerBasedTimestepper.SubGrid.VolumeMask); // Note: When being called, artificial viscosity is updated in the _ENTIRE_ (fluid) domain var avField = program.WorkingSet.DerivedFields[CNSVariables.ArtificialViscosity]; CNSVariables.ArtificialViscosity.UpdateFunction(avField, program.SpeciesMap.SubGrid.VolumeMask, program); // Test //double sensorNorm = program.WorkingSet.DerivedFields[CNSVariables.ShockSensor].L2Norm(); //double avNorm = program.WorkingSet.DerivedFields[CNSVariables.ArtificialViscosity].L2Norm(); //Console.WriteLine("\r\nThis is OnBeforeComputeChangeRate"); //Console.WriteLine("SensorNeu: {0}", sensorNorm); //Console.WriteLine("AVNeu: {0}", avNorm); }; } // Make sure limiter is applied after each modification of conservative variables if (control.Limiter != null) { ExplicitEuler explicitEulerBasedTimestepper = timeStepper as ExplicitEuler; if (explicitEulerBasedTimestepper == null) { throw new Exception(String.Format( "Limiting currently not implemented for time-steppers of type '{0}~", timeStepperType)); } explicitEulerBasedTimestepper.OnAfterFieldUpdate += (t, f) => control.Limiter.LimitFieldValues(program.WorkingSet.ConservativeVariables, program.WorkingSet.DerivedFields.Values); } return(timeStepper); }