/// <summary> /// Based on the Ideas by /// C. Basting and D. Kuzmin, /// “A minimization-based finite element formulation for interface-preserving level set reinitialization”, /// Computing, vol. 95, no. 1, pp. 13–25, Dec. 2012. /// </summary> /// <param name="LSTrck"></param> /// <param name="bcmap">Boundary Conditions for the LevelSet Equations</param> /// <param name="Control">various parameters <paramref name="EllipticReinitControl"/></param> public Extender(SinglePhaseField Extension, LevelSetTracker LSTrck, ILevelSetComponent InterfaceFlux, List <DGField> InterfaceParams, VectorField <SinglePhaseField> LevelSetGradient, EllipticExtVelAlgoControl Control) { if (InterfaceFlux.ParameterOrdering.Count != InterfaceParams.Count) { throw new ArgumentException("Missmatch in Number of Parameters and expected amount in the given flux."); } this.InterfaceParams = InterfaceParams; this.Control = Control; int D = LSTrck.GridDat.SpatialDimension; //this.InterfaceValue = InterfaceValue; //InterfaceValue.Identification = "InterfaceValue"; this.Extension = Extension; this.LevelSetTracker = LSTrck; Phi = LevelSetTracker.LevelSets[0] as LevelSet; this.LevelSetGradient = LevelSetGradient; switch (Control.FluxVariant) { case FluxVariant.GradientBased: // Flux Direction based on Mean Level Set Gradient MeanLevelSetGradient = new VectorField <SinglePhaseField>( D.ForLoop( d => new SinglePhaseField( new Basis(LSTrck.GridDat, 0), VariableNames.MeanLevelSetGradientComponent(d) ) ) ); BulkParams = new List <DGField> { }; BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray()); break; case FluxVariant.ValueBased: // Flux Direction Based on Cell-Averaged Level-Set Value MeanLevelSet = new SinglePhaseField(new Basis(LSTrck.GridDat, 0), "MeanLevelSet"); BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet); break; case FluxVariant.SWIP: BulkParams = LevelSetGradient.ToArray(); break; default: throw new NotImplementedException(); } this.D = LevelSetTracker.GridDat.SpatialDimension; double PenaltyBase = Control.PenaltyMultiplierFlux * ((double)((Phi.Basis.Degree + 1) * (Phi.Basis.Degree + D))) / ((double)D); DefineBulkOperator(LSTrck, InterfaceFlux, D, PenaltyBase); Operator_interface = InterfaceFlux.XOperator(QuadOrderFunc.FixedOrder(2 * Extension.Basis.Degree + 2)); }