/// <summary> /// Private constructor for cloning purposes /// </summary> /// <param name="gridData">The omnipresent grid data</param> /// <param name="config">Configurations options</param> /// <param name="template">The object to be cloned</param> protected CNSFieldSet(IGridData gridData, CNSControl config, CNSFieldSet template) { this.gridData = gridData; this.config = config; Density = template.Density.CloneAs(); DGField[] momentumComponents = new DGField[CNSEnvironment.NumberOfDimensions]; for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++) { momentumComponents[d] = template.Momentum[d].CloneAs(); } Momentum = new VectorField <DGField>(momentumComponents); Energy = template.Energy.CloneAs(); DerivedFields = new Dictionary <DerivedVariable, DGField>(); foreach (var variableFieldPair in template.DerivedFields) { DerivedFields.Add(variableFieldPair.Key, variableFieldPair.Value.CloneAs()); } }
/// <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); }