Example #1
0
        /// <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);
        }
Example #2
0
        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));
            }
        }
Example #3
0
        /// <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);
        }