Ejemplo n.º 1
0
 public IBMRungeKutta(
     SpatialOperator standardOperator,
     SpatialOperator boundaryOperator,
     CoordinateMapping fieldsMap,
     CoordinateMapping parametersMap,
     ImmersedSpeciesMap speciesMap,
     IList <TimeStepConstraint> timeStepConstraints)
     : base(RungeKutta.GetDefaultScheme(speciesMap.Control.ExplicitOrder), standardOperator, fieldsMap, parametersMap, timeStepConstraints, speciesMap.SubGrid)
 {
     this.speciesMap           = speciesMap;
     this.boundaryOperator     = boundaryOperator;
     this.boundaryParameterMap = parametersMap;
 }
Ejemplo n.º 2
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);
        }