Example #1
0
 public OperatorFactory(CNSControl control, BoundaryConditionMap boundaryMap)
 {
     this.control     = control;
     this.boundaryMap = boundaryMap;
     argumentOrdering = new string[control.Config.VariableOrdering.Count];
     control.Config.VariableOrdering.Keys.CopyTo(argumentOrdering, 0);
 }
Example #2
0
        /// <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());
            }
        }
Example #3
0
        /// <summary>
        /// Uses information from <paramref name="config"/> to create
        /// <see cref="SinglePhaseField"/>s for <see cref="Density"/>,
        /// <see cref="Momentum"/> and <see cref="Energy"/>.
        /// </summary>
        /// <param name="gridData">The omnipresent grid data</param>
        /// <param name="config">CNS specific control options</param>
        public CNSFieldSet(IGridData gridData, CNSControl config)
        {
            this.gridData = gridData;
            this.config   = config;

            int numberOfDimensions = CNSEnvironment.NumberOfDimensions;

            SinglePhaseField[] momentumFields = new SinglePhaseField[numberOfDimensions];
            Basis momentumBasis = new Basis(gridData, config.MomentumDegree);

            // Mandatory fields
            Density = new SinglePhaseField(
                new Basis(gridData, config.DensityDegree),
                Variables.Density);

            for (int d = 0; d < numberOfDimensions; d++)
            {
                string variableName = Variables.Momentum[d];
                momentumFields[d] = new SinglePhaseField(momentumBasis, variableName);
            }
            Momentum = new VectorField <DGField>(momentumFields);

            Energy = new SinglePhaseField(
                new Basis(gridData, config.EnergyDegree), Variables.Energy);

            // Derived fields
            foreach (var fieldConfig in config.VariableFields)
            {
                DerivedVariable key = fieldConfig.Key as DerivedVariable;
                if (key == null)
                {
                    continue;
                }

                SinglePhaseField field = new SinglePhaseField(
                    new Basis(gridData, fieldConfig.Value), key);
                DerivedFields.Add(key, field);
            }
        }
Example #4
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);
        }
Example #5
0
        /// <summary>
        /// Calculates the lift and drag force on given edges, e.g edges around an airfoil.
        /// Currently only in 2D!!!
        /// </summary>
        /// <param name="edgeTagName">EdgeTag on which the drag force will be calculated</param>
        /// <returns>total drag force</returns>
        /// <remarks>It assumes that pressure and velocity fields exists</remarks>
        public static Query LiftAndDragForce(String edgeTagName)
        {
            return(delegate(IApplication <AppControl> app, double time) {
                if (dragIntegral == null)
                {
                    densityField = app.IOFields.SingleOrDefault((f) => f.Identification == "rho");
                    m0Field = app.IOFields.SingleOrDefault((f) => f.Identification == "m0");
                    m1Field = app.IOFields.SingleOrDefault((f) => f.Identification == "m1");
                    energyField = app.IOFields.SingleOrDefault((f) => f.Identification == "rhoE");

                    DrhoDx = new SinglePhaseField(densityField.Basis);
                    DrhoDy = new SinglePhaseField(densityField.Basis);

                    Dm0Dx = new SinglePhaseField(m0Field.Basis);
                    Dm0Dy = new SinglePhaseField(m0Field.Basis);
                    Dm1Dx = new SinglePhaseField(m1Field.Basis);
                    Dm1Dy = new SinglePhaseField(m1Field.Basis);

                    CNSControl c = app.Control as CNSControl;
                    Program prog = app as Program;

                    byte edgeTag = app.Grid.EdgeTagNames.First(item => item.Value.Equals(edgeTagName)).Key;

                    CoordinateMapping mapping = new CoordinateMapping(
                        densityField, m0Field, m1Field, energyField, DrhoDx, DrhoDy, Dm0Dx, Dm0Dy, Dm1Dx, Dm1Dy);

                    dragIntegral = new EdgeIntegral((BoSSS.Foundation.Grid.Classic.GridData)(app.GridData), edgeTag, new ForceFlux(
                                                        c.ReynoldsNumber, prog.SpeciesMap.GetMaterial(double.NaN), 0), mapping);
                    liftIntegral = new EdgeIntegral((BoSSS.Foundation.Grid.Classic.GridData)(app.GridData), edgeTag, new ForceFlux(
                                                        c.ReynoldsNumber, prog.SpeciesMap.GetMaterial(double.NaN), 1), mapping);

                    if (logger == null && app.CurrentSessionInfo.ID != Guid.Empty && app.MPIRank == 0)
                    {
                        logger = app.DatabaseDriver.FsDriver.GetNewLog("LiftAndDragForce", app.CurrentSessionInfo.ID);
                        string header = "PhysTime\t LiftForce\t DragForce";
                        logger.WriteLine(header);
                    }
                }

                DrhoDx.Clear();
                DrhoDy.Clear();

                DrhoDx.Derivative(1.0, densityField, 0);
                DrhoDy.Derivative(1.0, densityField, 1);

                Dm0Dx.Clear();
                Dm0Dy.Clear();
                Dm1Dx.Clear();
                Dm1Dy.Clear();

                Dm0Dx.Derivative(1.0, m0Field, 0);
                Dm0Dy.Derivative(1.0, m0Field, 1);
                Dm1Dx.Derivative(1.0, m1Field, 0);
                Dm1Dy.Derivative(1.0, m1Field, 1);

                double lift = liftIntegral.Evaluate();
                double drag = dragIntegral.Evaluate();

                if (logger != null && app.MPIRank == 0)
                {
                    string line = time + "\t" + lift + "\t" + drag;
                    logger.WriteLine(line);
                    logger.Flush();
                }
                return drag;
            });
        }