/// <summary> /// Specifies the control object for application startup; overrides any startup arguments (<see cref="CommandLineArguments"/>) /// set so far. /// </summary> public void SetControlObject(BoSSS.Solution.Control.AppControl ctrl) { TestActivation(); // serialize control object // ======================== // grid function hack: if (ctrl.GridFunc != null) { Console.WriteLine("Control object contains grid function. Trying to Serialize the grid..."); var dbi = ctrl.GetDatabase(); if (dbi == null) { throw new NotSupportedException("If a gird function is specified (instead of a grid id), a database must be specified to save the gird (when using the job manager)."); } Foundation.Grid.IGrid g = ctrl.GridFunc(); Guid id = dbi.SaveGrid(ref g); ctrl.GridFunc = null; ctrl.GridGuid = id; Console.WriteLine("Control object modified."); } ctrl.VerifyEx(); m_ctrl = ctrl; m_ctrl.ProjectName = InteractiveShell.WorkflowMgm.CurrentProject; // note: serialization is done later, immediately before deployment, // since we may need to fix database issues (path on batch system, evtl. transfer of grid) m_ctrl_index = -1; if (m_ctrl.GeneratedFromCode) { ControlName = "control.cs"; m_ctrl_index = m_ctrl.ControlFileText_Index; } else { ControlName = "control.obj"; } // Project & Session Name // ====================== string PrjName = InteractiveShell.WorkflowMgm.CurrentProject; if (string.IsNullOrWhiteSpace(PrjName)) { throw new NotSupportedException("Project management not initialized - set project name (try e.g. 'WorkflowMgm.CurrentProject = \"BlaBla\"')."); } string[] args = new string[] { "--control", "control.obj", "--prjnmn", PrjName, "--sesnmn", this.Name }; if (m_ctrl_index >= 0) { ArrayTools.Cat(args, "--pstudy_case", m_ctrl_index.ToString()); } m_EnvironmentVars.Clear(); for (int i = 0; i < args.Length; i++) { m_EnvironmentVars.Add("BOSSS_ARG_" + i, args[i]); } // }
/// <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. /// Create Spatial Operators and build the corresponding Matrices /// For the Left-Hand Side of the ReInitProblem /// RHS is computed on the fly in <see cref="ReInitSingleStep"/> /// The Bulk component is constant unless the grid changes, thus it is computed in <see cref="BuildOperators(CellQuadratureScheme)"/>. /// The Interface component changes with its motion. /// This component is calculated in <see cref="UpdateOperators(CellQuadratureScheme)"/>. /// </summary> /// <param name="LSTrck"></param> /// <param name="Control">various parameters <paramref name="EllipticReinitControl"/></param> /// <param name="HMFOrder">order of tghe interface quadrature</param> public EllipticReInit(LevelSetTracker LSTrck, EllipticReInitAlgoControl Control, SinglePhaseField LevelSetForReInit = null) { this.Control = Control; this.LevelSetTracker = LSTrck; if (LevelSetForReInit == null) { Phi = LevelSetTracker.LevelSets[0] as SinglePhaseField; } else { Phi = LevelSetForReInit; } this.underrelaxation = Control.underrelaxation; Residual = new SinglePhaseField(Phi.Basis); OldPhi = new SinglePhaseField(Phi.Basis); NewPhi = new SinglePhaseField(Phi.Basis); foreach (SinglePhaseField f in new List <SinglePhaseField> { Residual, OldPhi, NewPhi }) { f.Clear(); f.Acc(1.0, Phi); } this.D = LevelSetTracker.GridDat.SpatialDimension; this.ConvergenceCriterion = Control.ConvergenceCriterion; this.MaxIteration = Control.MaxIt; double PenaltyBase = ((double)((Phi.Basis.Degree + 1) * (Phi.Basis.Degree + D))) / ((double)D); // Choose Forms according to Upwinding or Central Fluxes string[] paramNames; int noOfParamFields; IEquationComponent BulkForm; RHSForm myRHSForm; LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, "LevelSetGradient", SinglePhaseField.Factory); MeanLevelSetGradient = new VectorField <SinglePhaseField>(D, new Basis(Phi.GridDat, 0), "MeanLevelSetGradient", SinglePhaseField.Factory); if (Control.Upwinding) { paramNames = new string[] { "OldLevelSet", "MeanLevelSetGradient[0]", "MeanLevelSetGradient[1]" }; noOfParamFields = D; LevelSetGradient.Clear(); LevelSetGradient.Gradient(1.0, Phi); //LevelSetGradient.GradientByFlux(1.0, Phi); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); parameterFields = ArrayTools.Cat(new SinglePhaseField[] { OldPhi }, MeanLevelSetGradient.ToArray()); //throw new NotImplementedException("ToDO"); BulkForm = new EllipticReInitUpwindForm_Laplace(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); myRHSForm = new EllipticReInitUpwindForm_RHS(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); OldDirection = new double[MeanLevelSetGradient.CoordinateVector.ToArray().Length]; for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++) { OldDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]); } NewDirection = OldDirection.CloneAs(); } else { paramNames = new string[] { }; noOfParamFields = 0; parameterFields = new SinglePhaseField[] { }; BulkForm = new CentralDifferencesLHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck.GridDat.Cells.cj); myRHSForm = new CentralDifferencesRHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck); } // SIP for the bulk Phase //this.Operator_bulk = new SpatialOperator(1, noOfParamFields, 1, QuadOrderFunc.SumOfMaxDegrees(1, RoundUp: false), variableNames); this.Operator_bulk = BulkForm.Operator(); // Zero at the Interface // Calculate Quadrature Order Func <int[], int[], int[], int> InterfaceQuadOrder; InterfaceQuadOrder = QuadOrderFunc.FixedOrder(Phi.Basis.Degree * 2 + 2); // Generate Interface Operator this.Operator_interface = (new EllipticReInitInterfaceForm(Control.PenaltyMultiplierInterface * PenaltyBase, LSTrck)).XOperator(new[] { "A" }, InterfaceQuadOrder); // Nonlinear Part on the RHS // switch for the potential functions switch (Control.Potential) { case ReInitPotential.BastingDoubleWell: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWell(d, b)); break; }; case ReInitPotential.BastingSingleWell: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWell(d, b)); break; }; case ReInitPotential.SingleWellNear: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellNear(d, b)); break; }; case ReInitPotential.P4DoubleWell: { Console.WriteLine("Warning - This Option for Elliptic ReInit does not work well"); myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWellAlternative(d, b)); break; }; case ReInitPotential.SingleWellOnCutDoubleWellElse: { myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellOnCutDoubleWellElse(d, b)); break; } } Operator_RHS = myRHSForm.Operator(QuadOrderFunc.SumOfMaxDegrees(2, RoundUp: true)); // The result of the nonlinear part on the rhs is projected on a single-phase field RHSField = new SinglePhaseField(Phi.Basis, "RHS"); OpMatrix = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine = new double[OpMatrix.RowPartitioning.LocalLength]; // Matrix and RHS for the Bulk component OpMatrix_bulk = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength]; // Matrix and RHS for the Interface Penalty OpMatrix_interface = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping); OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength]; // Init Parameter Fields OldPhi.Clear(); OldPhi.Acc(1.0, Phi); // Compute Matrices UpdateBulkMatrix(); }
static void InfoRecursive(object obj, int RecursionDepth, int MaxRecursionDepth) { if (obj == null) { Console.WriteLine("Null"); return; } if (RecursionDepth > MaxRecursionDepth) { Console.WriteLine(" ... no further recursion - max recursion depth reached."); return; } Type objT = obj.GetType(); if ((objT.IsPrimitive || objT.IsEnum || objT == typeof(string))) { Console.WriteLine(obj.ToString() + " (" + objT.Name + ")"); return; } if (objT.IsSubclassOf(typeof(System.Delegate))) { // unable to log delegates Console.WriteLine("Delegate"); return; } void WriteSpaces() { //Console.WriteLine(); for (int i = 0; i < RecursionDepth; i++) { Console.Write(" "); } } if (obj is System.Collections.IEnumerable) { System.Collections.IEnumerable objEnu = (System.Collections.IEnumerable)obj; int cnt = 0; foreach (var objE in objEnu) { WriteSpaces(); Console.Write("[{0}]: ", cnt); cnt++; InfoRecursive(objE, RecursionDepth + 1, MaxRecursionDepth); } return; } BindingFlags biFlags = BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty; MemberInfo[] PIs = objT.GetProperties(biFlags); MemberInfo[] FIs = objT.GetFields(biFlags); foreach (MemberInfo mi in ArrayTools.Cat(PIs, FIs)) { WriteSpaces(); Console.Write(mi.Name + ": "); object Val; if (mi is PropertyInfo) { PropertyInfo pi = ((PropertyInfo)mi); if (!pi.CanRead) { Console.WriteLine("cannot read."); continue; } if (pi.GetIndexParameters() != null && pi.GetIndexParameters().Length > 0) { // no support for indexed properties. Console.WriteLine("indexed property - not supported."); continue; } //pi.GetIndexParameters try { Val = pi.GetValue(obj, biFlags, null, null, null); } catch (TargetInvocationException tie) { Console.WriteLine(tie.GetType().Name + ": " + tie.Message); continue; } } else if (mi is FieldInfo) { Val = ((FieldInfo)mi).GetValue(obj); } else { Console.WriteLine("unsupported member type: " + mi.GetType().FullName + "."); continue; } InfoRecursive(Val, RecursionDepth + 1, MaxRecursionDepth); } }
public OperatorFactory( OperatorConfiguration config, LevelSetTracker _LsTrk, int _HMFdegree, int degU, IncompressibleMultiphaseBoundaryCondMap BcMap, bool _movingmesh, bool _evaporation, bool _staticInt) { // variable names // ============== D = _LsTrk.GridDat.SpatialDimension; this.LsTrk = _LsTrk; //this.momentFittingVariant = momentFittingVariant; this.HMFDegree = _HMFdegree; this.dntParams = config.dntParams.CloneAs(); this.physParams = config.physParams.CloneAs(); this.UseExtendedVelocity = config.UseXDG4Velocity; this.movingmesh = _movingmesh; this.evaporation = _evaporation; // test input // ========== { if (config.DomBlocks.GetLength(0) != 2 || config.CodBlocks.GetLength(0) != 2) { throw new ArgumentException(); } if (config.physParams.mu_A == 0.0 && config.physParams.mu_B == 0.0) { muIs0 = true; } else { if (config.physParams.mu_A <= 0) { throw new ArgumentException(); } if (config.physParams.mu_B <= 0) { throw new ArgumentException(); } } if (config.physParams.rho_A <= 0) { throw new ArgumentException(); } if (config.physParams.rho_B <= 0) { throw new ArgumentException(); } if (_LsTrk.SpeciesNames.Count != 2) { throw new ArgumentException(); } if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B"))) { throw new ArgumentException(); } } // full operator: CodName = ((new string[] { "momX", "momY", "momZ" }).GetSubVector(0, D)).Cat("div"); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), "Curvature", (new string[] { "surfForceX", "surfForceY", "surfForceZ" }).GetSubVector(0, D), (new string[] { "NX", "NY", "NZ" }).GetSubVector(0, D), (new string[] { "GradTempX", "GradTempY", "GradTempZ" }.GetSubVector(0, D)), VariableNames.Temperature, "DisjoiningPressure"); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure); // selected part: if (config.CodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D)); } if (config.CodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1)); } if (config.DomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D)); } if (config.DomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1)); } muA = config.physParams.mu_A; muB = config.physParams.mu_B; rhoA = config.physParams.rho_A; rhoB = config.physParams.rho_B; sigma = config.physParams.Sigma; MatInt = !evaporation; double kA = 0.0; double kB = 0.0; double hVapA = 0.0; double hVapB = 0.0; double Tsat = 0.0; double R_int = 0.0; double p_c = 0.0; if (evaporation) { kA = config.thermParams.k_A; kB = config.thermParams.k_B; hVapA = config.thermParams.hVap_A; hVapB = config.thermParams.hVap_B; Tsat = config.thermParams.T_sat; p_c = config.thermParams.pc; //double T_intMin = 0.0; double f = config.thermParams.fc; double R = config.thermParams.Rc; //double pc = config.thermParams.pc; if (config.thermParams.hVap_A > 0 && config.thermParams.hVap_B < 0) { R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoB * hVapA.Pow2()); //T_intMin = Tsat * (1 + (pc / (rhoA * hVapA.Pow2()))); } else if (config.thermParams.hVap_A < 0 && config.thermParams.hVap_B > 0) { R_int = ((2.0 - f) / (2 * f)) * Tsat * Math.Sqrt(2 * Math.PI * R * Tsat) / (rhoA * hVapB.Pow2()); //T_intMin = Tsat * (1 + (pc / (rhoB * hVapB.Pow2()))); } this.CurvatureRequired = true; } //if (!MatInt) // throw new NotSupportedException("Non-Material interface is NOT tested!"); // create Operator // =============== m_OP = new XSpatialOperator(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree); // build the operator // ================== { // Momentum equation // ================= if (config.physParams.IncludeConvection && config.Transport) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; // convective part: // variante 1: double LFFA = config.dntParams.LFFA; double LFFB = config.dntParams.LFFB; var conv = new Operator.Convection.ConvectionInBulk_LLF(D, BcMap, d, rhoA, rhoB, LFFA, LFFB, LsTrk); comps.Add(conv); // Bulk component comps.Add(new Operator.Convection.ConvectionAtLevelSet_LLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, config.physParams.Material, BcMap, movingmesh)); // LevelSet component //comps.Add(new Operator.Convection.ConvectionAtLevelSet_weightedLLF(d, D, LsTrk, rhoA, rhoB, LFFA, LFFB, BcMap, movingmesh)); // LevelSet component if (evaporation) { //comps.Add(new Operator.Convection.ConvectionAtLevelSet_Divergence(d, D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterialLLF(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); //comps.Add(new Operator.Convection.ConvectionAtLevelSet_nonMaterial(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } // variante 3: //var convA = new LocalConvection(D, d, rhoA, rhoB, this.config.varMode, LsTrk); //XOP.OnIntegratingBulk += convA.SetParameter; //comps.Add(convA); //////var convB = new LocalConvection2(D, d, rhoA, rhoB, varMode, LsTrk); // macht Bum-Bum! ////XOP.OnIntegratingBulk += convB.SetParameter; ////comps.Add(convB); } this.U0meanrequired = true; } // pressure gradient // ================= if (config.PressureGradient) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; var pres = new Operator.Pressure.PressureInBulk(d, BcMap); comps.Add(pres); //if (!MatInt) // throw new NotSupportedException("New Style pressure coupling does not support non-material interface."); var presLs = new Operator.Pressure.PressureFormAtLevelSet(d, D, LsTrk); //, dntParams.UseWeightedAverages, muA, muB); comps.Add(presLs); //if (evaporation) { // var presLSGen = new Operator.Pressure.GeneralizedPressureFormAtLevelSet(d, D, LsTrk, config.thermParams.p_sat, hVapA); // comps.Add(presLSGen); //} } } // viscous operator // ================ if (config.Viscous && !muIs0) { for (int d = 0; d < D; d++) { var comps = m_OP.EquationComponents[CodName[d]]; // viscous part: //double _D = D; //double penalty_mul = dntParams.PenaltySafety; //double _p = degU; //double penalty_base = (_p + 1) * (_p + _D) / _D; //double penalty = penalty_base * penalty_mul; double penalty = dntParams.PenaltySafety; switch (dntParams.ViscosityMode) { case ViscosityMode.Standard: { // Bulk operator: var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); // , _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } // Level-Set operator: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, true)); break; } case ViscosityMode.TransposeTermMissing: { // Bulk operator: var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } // Level-Set operator: comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Standard(LsTrk, muA, muB, penalty * 1.0, d, false)); break; } case ViscosityMode.ExplicitTransformation: { // Bulk operator var Visc = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); comps.Add(Visc); if (dntParams.UseGhostPenalties) { var ViscPenalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm(penalty * 1.0, 0.0, BcMap, d, D, muA, muB); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(ViscPenalty); } //Level-Set operator: //comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_Explicit(d, D, LsTrk, penalty, muA, muB)); throw new NotSupportedException("Beim refact rausgeflogen, braucht eh kein Mensch. fk, 08jan16."); //break; } case ViscosityMode.FullySymmetric: { // Bulk operator var Visc1 = new Operator.Viscosity.ViscosityInBulk_GradUTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B); var Visc2 = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm( dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB, _betaA: this.physParams.betaS_A, _betaB: this.physParams.betaS_B); //var Visc3 = new Operator.Viscosity.ViscosityInBulk_divTerm(dntParams.UseGhostPenalties ? 0.0 : penalty, 1.0, BcMap, d, D, muA, muB); comps.Add(Visc1); comps.Add(Visc2); //comps.Add(Visc3); if (dntParams.UseGhostPenalties) { var Visc1Penalty = new Operator.Viscosity.ViscosityInBulk_GradUTerm( penalty, 0.0, BcMap, d, D, muA, muB); var Visc2Penalty = new Operator.Viscosity.ViscosityInBulk_GradUtranspTerm( penalty, 0.0, BcMap, d, D, muA, muB); //var Visc3Penalty = new Operator.Viscosity.ViscosityInBulk_divTerm( // penalty, 0.0, // BcMap, d, D, muA, muB); //m_OP.OnIntegratingBulk += Visc3Penalty.SetParameter; m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc1Penalty); m_OP.GhostEdgesOperator.EquationComponents[CodName[d]].Add(Visc2Penalty); //m_OP.AndresHint.EquationComponents[CodName[d]].Add(Visc3Penalty); } // Level-Set operator comps.Add(new Operator.Viscosity.ViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, _staticInt, dntParams.UseWeightedAverages)); if (this.evaporation) { comps.Add(new Operator.Viscosity.GeneralizedViscosityAtLevelSet_FullySymmetric(LsTrk, muA, muB, penalty, d, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } break; } default: throw new NotImplementedException(); } } } // Continuum equation // ================== if (config.continuity) { for (int d = 0; d < D; d++) { var src = new Operator.Continuity.DivergenceInBulk_Volume(d, D, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti); var flx = new Operator.Continuity.DivergenceInBulk_Edge(d, BcMap, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti); m_OP.EquationComponents["div"].Add(flx); m_OP.EquationComponents["div"].Add(src); } var divPen = new Operator.Continuity.DivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, MatInt, config.dntParams.ContiSign, config.dntParams.RescaleConti, _staticInt); //, dntParams.UseWeightedAverages, muA, muB); m_OP.EquationComponents["div"].Add(divPen); if (evaporation) { var divPenGen = new Operator.Continuity.GeneralizedDivergenceAtLevelSet(D, LsTrk, rhoA, rhoB, config.dntParams.ContiSign, config.dntParams.RescaleConti, kA, kB, hVapA, R_int, Tsat, sigma, p_c); m_OP.EquationComponents["div"].Add(divPenGen); } //// pressure stabilization //if (this.config.PressureStab) { // Console.WriteLine("Pressure Stabilization active."); //var pStabi = new PressureStabilization(0.0001, 0.0001); // m_OP.OnIntegratingBulk += pStabi.SetParameter; // m_OP.EquationComponents["div"].Add(pStabi); ////var pStabiLS = new PressureStabilizationAtLevelSet(D, LsTrk, rhoA, muA, rhoB, muB, sigma, this.config.varMode, MatInt); // //XOP.EquationComponents["div"].Add(pStabiLS); //} else { // Console.WriteLine("Pressure Stabilization INACTIVE."); //} } // surface tension // =============== if (config.PressureGradient && config.physParams.Sigma != 0.0) { // isotropic part of the surface stress tensor if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Local || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { for (int d = 0; d < D; d++) { if (config.dntParams.SST_isotropicMode != SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_ContactLine) { IEquationComponent G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5); IEquationComponent H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.LaplaceBeltrami_Flux); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H); } else { //G = new SurfaceTension_LaplaceBeltrami2_Surface(d, config.physParams.Sigma * 0.5); //H = new SurfaceTension_LaplaceBeltrami2_BndLine(d, config.physParams.Sigma * 0.5, config.physParams.Theta_e, config.physParams.betaL); IEquationComponent isoSurfT = new IsotropicSurfaceTension_LaplaceBeltrami(d, D, config.physParams.Sigma * 0.5, BcMap.EdgeTag2Type, BcMap, config.physParams.theta_e, config.physParams.betaL, _staticInt); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(isoSurfT); } } this.NormalsRequired = true; } else if (config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Projected || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_ClosestPoint || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_LaplaceBeltramiMean || config.dntParams.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new CurvatureBasedSurfaceTension(d, D, LsTrk, config.physParams.Sigma)); } this.CurvatureRequired = true; /* * Console.WriteLine("REM: hack in Operator factory"); * for(int d = 0; d < D; d++) { * //var G = new SurfaceTension_LaplaceBeltrami_Surface(d, config.physParams.Sigma * 0.5); * var H = new SurfaceTension_LaplaceBeltrami_BndLine(d, config.physParams.Sigma * 0.5, config.dntParams.surfTensionMode == SurfaceTensionMode.LaplaceBeltrami_Flux); * * //m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(G); * m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(H); * } * * this.NormalsRequired = true; */ } else { throw new NotImplementedException("Not implemented."); } // dynamic part if (config.dntParams.SurfStressTensor != SurfaceSressTensor.Isotropic) { double muI = config.physParams.mu_I; double lamI = config.physParams.lambda_I; double penalty_base = (degU + 1) * (degU + D) / D; double penalty = penalty_base * dntParams.PenaltySafety; // surface shear viscosity if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceRateOfDeformation || config.dntParams.SurfStressTensor == SurfaceSressTensor.SemiImplicit || config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { for (int d = 0; d < D; d++) { var surfDeformRate = new BoussinesqScriven_SurfaceDeformationRate_GradU(d, muI * 0.5, penalty); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRate); //m_OP.OnIntegratingSurfaceElement += surfDeformRate.SetParameter; if (config.dntParams.SurfStressTensor != SurfaceSressTensor.SemiImplicit) { var surfDeformRateT = new BoussinesqScriven_SurfaceDeformationRate_GradUTranspose(d, muI * 0.5, penalty); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfDeformRateT); //m_OP.OnIntegratingSurfaceElement += surfDeformRateT.SetParameter; } } } // surface dilatational viscosity if (config.dntParams.SurfStressTensor == SurfaceSressTensor.SurfaceVelocityDivergence || config.dntParams.SurfStressTensor == SurfaceSressTensor.FullBoussinesqScriven) { for (int d = 0; d < D; d++) { var surfVelocDiv = new BoussinesqScriven_SurfaceVelocityDivergence(d, muI * 0.5, lamI * 0.5, penalty, BcMap.EdgeTag2Type); m_OP.SurfaceElementOperator.EquationComponents[CodName[d]].Add(surfVelocDiv); //m_OP.OnIntegratingSurfaceElement += surfVelocDiv.SetParameter; } } } // stabilization if (config.dntParams.UseLevelSetStabilization) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new LevelSetStabilization(d, D, LsTrk)); } } } // surface force term // ================== if (config.PressureGradient && config.physParams.useArtificialSurfaceForce) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new SurfaceTension_ArfForceSrc(d, D, LsTrk)); } } // evaporation (mass flux) // ======================= if (evaporation) { for (int d = 0; d < D; d++) { m_OP.EquationComponents[CodName[d]].Add(new Operator.DynamicInterfaceConditions.MassFluxAtInterface(d, D, LsTrk, rhoA, rhoB, kA, kB, hVapA, R_int, Tsat, sigma, p_c)); } } } // Finalize // ======== m_OP.Commit(); }
/// <summary> /// ctor for the operator factory, where the equation compnents are set /// </summary> /// <param name="config"></param> /// <param name="_LsTrk"></param> /// <param name="_HMFdegree"></param> /// <param name="BcMap"></param> /// <param name="degU"></param> public XNSE_OperatorFactory(IXNSE_Configuration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int degU) { this.LsTrk = _LsTrk; this.D = _LsTrk.GridDat.SpatialDimension; this.HMFDegree = _HMFdegree; this.physParams = config.getPhysParams; this.dntParams = config.getDntParams; // test input // ========== { if (config.getDomBlocks.GetLength(0) != 2 || config.getCodBlocks.GetLength(0) != 2) { throw new ArgumentException(); } if ((config.getPhysParams.mu_A <= 0) && (config.getPhysParams.mu_B <= 0)) { config.isViscous = false; } else { if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0)) { throw new ArgumentException(); } } if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.rho_B <= 0)) { throw new ArgumentException(); } if (_LsTrk.SpeciesNames.Count != 2) { throw new ArgumentException(); } if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B"))) { throw new ArgumentException(); } } // full operator: // ============== CodName = ArrayTools.Cat(EquationNames.MomentumEquations(D), EquationNames.ContinuityEquation); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), VariableNames.NormalVector(D), VariableNames.Curvature, VariableNames.SurfaceForceVector(D) ); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure); // selected part: if (config.getCodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D)); } if (config.getCodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1)); } if (config.getDomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D)); } if (config.getDomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1)); } // create Operator // =============== m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray()); // add components // ============== // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { // Navier Stokes equations XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); // continuity equation if (config.isContinuity) { XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap); } } // interface components XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk); // surface stress tensor XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force if (config.isContinuity) { XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk); // continuity equation } m_XOp.Commit(); }
/// <summary> /// ctor for the operator factory, where the equation compnents are set /// </summary> /// <param name="_config"></param> /// <param name="_LsTrk"></param> /// <param name="_HMFdegree"></param> /// <param name="BcMap"></param> /// <param name="thermBcMap"></param> /// <param name="degU"></param> public XNSFE_OperatorFactory(XNSFE_OperatorConfiguration _config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, ThermalMultiphaseBoundaryCondMap thermBcMap, int degU, IDictionary <SpeciesId, IEnumerable <double> > MassScale) { this.config = _config; this.LsTrk = _LsTrk; this.D = _LsTrk.GridDat.SpatialDimension; this.HMFDegree = _HMFdegree; this.physParams = config.getPhysParams; this.thermParams = config.getThermParams; this.dntParams = config.getDntParams; // test input // ========== { if ((config.getPhysParams.mu_A <= 0) && (config.getPhysParams.mu_B <= 0)) { config.isViscous = false; } else { if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0)) { throw new ArgumentException(); } } if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.rho_B <= 0)) { throw new ArgumentException(); } if (_LsTrk.SpeciesNames.Count != 2) { throw new ArgumentException(); } if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B"))) { throw new ArgumentException(); } } // full operator: // ============== CodName = ArrayTools.Cat(EquationNames.MomentumEquations(D), EquationNames.ContinuityEquation); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D), VariableNames.Velocity0MeanVector(D), VariableNames.NormalVector(D), VariableNames.Curvature, VariableNames.SurfaceForceVector(D) ); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D), VariableNames.Pressure); if (config.solveEnergy) { CodName = ArrayTools.Cat(CodName, EquationNames.KineticEnergyEquation); Params = ArrayTools.Cat(Params, VariableNames.VelocityX_GradientVector(), VariableNames.VelocityY_GradientVector(), new string[] { "VelocityXGradX_GradientX", "VelocityXGradX_GradientY" }, new string[] { "VelocityXGradY_GradientX", "VelocityXGradY_GradientY" }, new string[] { "VelocityYGradX_GradientX", "VelocityYGradX_GradientY" }, new string[] { "VelocityYGradY_GradientX", "VelocityYGradY_GradientY" }, VariableNames.Pressure0, VariableNames.PressureGradient(D), VariableNames.GravityVector(D) ); DomName = ArrayTools.Cat(DomName, VariableNames.KineticEnergy); } if (config.solveHeat) { Params = ArrayTools.Cat(Params, VariableNames.Temperature0, VariableNames.HeatFlux0Vector(D), VariableNames.DisjoiningPressure ); if (config.conductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP) { CodName = ArrayTools.Cat(CodName, EquationNames.HeatEquation); DomName = ArrayTools.Cat(DomName, VariableNames.Temperature); } else { CodName = ArrayTools.Cat(CodName, EquationNames.HeatEquation, EquationNames.AuxHeatFlux(D)); DomName = ArrayTools.Cat(DomName, VariableNames.Temperature, VariableNames.HeatFluxVector(D)); } } storedParams = new DGField[Params.Length]; // selected part: if (config.getCodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, D)); } if (config.getCodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D, 1)); } if (config.getDomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, D)); } if (config.getDomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D, 1)); } int nBlocks = 2; if (config.solveEnergy) { nBlocks = 3; if (config.getCodBlocks[2]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(D + 1, 1)); } if (config.getDomBlocks[2]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(D + 1, 1)); } } if (config.solveHeat) { if (config.getCodBlocks[nBlocks]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(nBlocks + (D - 1) + 1, 1)); } if (config.getDomBlocks[nBlocks]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(nBlocks + (D - 1) + 1, 1)); } if (config.conductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP) { if (config.getCodBlocks[nBlocks + 1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(nBlocks + (D - 1) + 2, D)); } if (config.getDomBlocks[nBlocks + 1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(nBlocks + (D - 1) + 2, D)); } } } // create Operator // =============== m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesNames); // add Navier-Stokes components // ============================ // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { // Navier Stokes equations Solution.XNSECommon.XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); // continuity equation if (config.isContinuity) { Solution.XNSECommon.XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap); } } // interface components Solution.XNSECommon.XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, D, BcMap, LsTrk); // surface stress tensor Solution.XNSECommon.XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force if (config.isContinuity) { Solution.XNSECommon.XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, D, LsTrk); // continuity equation } // add kinetic energy equation components // ====================================== if (config.solveEnergy) { // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { Solution.EnergyCommon.XOperatorComponentsFactory.AddSpeciesKineticEnergyEquation(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk); } // interface components Solution.EnergyCommon.XOperatorComponentsFactory.AddInterfaceKineticEnergyEquation(m_XOp, config, D, BcMap, LsTrk, degU); CurvatureRequired = true; } // add Heat equation components // ============================ if (config.solveHeat) { // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { Solution.XheatCommon.XOperatorComponentsFactory.AddSpeciesHeatEq(m_XOp, config, D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], thermBcMap, LsTrk); } // interface components Solution.XheatCommon.XOperatorComponentsFactory.AddInterfaceHeatEq(m_XOp, config, D, thermBcMap, LsTrk); } // add Evaporation interface components // ==================================== if (config.isEvaporation) { XOperatorComponentsFactory.AddInterfaceNSE_withEvaporation(m_XOp, config, D, LsTrk); if (config.isContinuity) { XOperatorComponentsFactory.AddInterfaceContinuityEq_withEvaporation(m_XOp, config, D, LsTrk); } } // create temporal operator // ======================== var TempOp = new ConstantXTemporalOperator(m_XOp, 0.0); m_XOp.TemporalOperator = TempOp; foreach (var kv in MassScale) { TempOp.DiagonalScale[LsTrk.GetSpeciesName(kv.Key)].SetV(kv.Value.ToArray()); } // Finalize // ======== m_XOp.Commit(); }
public ExtensionVelocityBDFMover(LevelSetTracker LSTrk, SinglePhaseField LevelSet, VectorField <SinglePhaseField> LevelSetGradient, VectorField <DGField> Velocity, EllipticExtVelAlgoControl Control, IncompressibleBoundaryCondMap bcMap, int BDForder, VectorField <SinglePhaseField> VectorExtension, double[] Density = null, bool AssumeDivergenceFreeVelocity = false, SubGrid subGrid = null) { this.GridDat = LSTrk.GridDat; D = GridDat.SpatialDimension; this.LevelSetGradient = LevelSetGradient; this.LSTrk = LSTrk; this.LevelSet = LevelSet; this.Velocity = Velocity; this.OldRHS = LevelSet.CloneAs(); this.AdvectionSpatialOperator = CreateAdvectionSpatialOperator(bcMap); this.subGrid = subGrid; this.nearfield = subGrid != null; Basis NonXVelocityBasis; if (Velocity == null) { throw new ArgumentException("Velocity Field not initialized!"); } // Initialize Extension Velocity Algorithm double PenaltyBase = Control.PenaltyMultiplierInterface * ((double)((LevelSet.Basis.Degree + 1) * (LevelSet.Basis.Degree + D))) / ((double)D); ILevelSetForm InterfaceFlux; //VectorExtension = new VectorField<SinglePhaseField>(D, Velocity[0].Basis, "ExtVel", SinglePhaseField.Factory); if (Velocity[0].GetType() == typeof(SinglePhaseField)) { NonXVelocityBasis = ((SinglePhaseField)Velocity[0]).Basis; InterfaceFlux = new SingleComponentInterfaceForm(PenaltyBase, LSTrk); } else if (Velocity[0].GetType() == typeof(XDGField)) { NonXVelocityBasis = ((XDGField)Velocity[0]).Basis.NonX_Basis; InterfaceFlux = new DensityWeightedExtVel(PenaltyBase, LSTrk, Density); } else { throw new ArgumentException("VelocityField must be either a SinglePhaseField or a XDGField!"); }; //VectorExtension = new VectorField<SinglePhaseField>(D, NonXVelocityBasis, "ExtVel", SinglePhaseField.Factory); this.VectorExtension = VectorExtension; VelocityExtender = new Extender[D]; for (int d = 0; d < D; d++) { VelocityExtender[d] = new Extender(VectorExtension[d], LSTrk, InterfaceFlux, new List <DGField> { Velocity[d] }, LevelSetGradient, Control); VelocityExtender[d].ConstructExtension(new List <DGField> { Velocity[d] }, Control.subGridRestriction); } #if DEBUG VectorExtension.CheckForNanOrInf(); #endif // Initialize Advection Algorithm divU = new SinglePhaseField(NonXVelocityBasis); divU.Identification = "Divergence"; divU.Clear(); divU.Divergence(1.0, VectorExtension); MeanVelocity = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(new Basis(GridDat, 0), VariableNames.Velocity0MeanVector(D)[d]))); MeanVelocity.Clear(); MeanVelocity.AccLaidBack(1.0, VectorExtension); myBDFTimestepper = new BDFTimestepper(AdvectionSpatialOperator, new List <DGField>() { LevelSet }, ArrayTools.Cat(VectorExtension, this.MeanVelocity, this.divU), BDForder, Control.solverFactory, false, subGrid); }
public void Init(MultigridOperator op) { int D = op.GridData.SpatialDimension; CodName = (new string[] { "mom0", "mom1" }); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D)); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D)); LocalOp = new SpatialOperator(DomName, Params, CodName, (A, B, C) => 4); for (int d = 0; d < D; d++) { LocalOp.EquationComponents["mom" + d].Add(new LocalDiffusiveFlux() { m_component = d, dt = m_dt, muA = m_muA }); } LocalOp.Commit(); //LocalMatrix = op.MassMatrix.CloneAs().ToMsrMatrix(); //LocalMatrix.Clear(); //var U0 = new VectorField<SinglePhaseField>(op.BaseGridProblemMapping Take(D).Select(F => (SinglePhaseField)F).ToArray()); UnsetteledCoordinateMapping test = new UnsetteledCoordinateMapping(op.BaseGridProblemMapping.BasisS.GetSubVector(0, D)); var U0 = ((BoSSS.Foundation.CoordinateMapping)op.Mapping.ProblemMapping).Fields.GetSubVector(0, 2); var empty = new SinglePhaseField[D]; LocalMatrix = LocalOp.ComputeMatrix(test, empty, test, time: m_dt); Uidx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, D.ForLoop(i => i)); Pidx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, D); int Upart = Uidx.Length; int Ppart = Pidx.Length; ConvDiff = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); pGrad = null; // new BlockMsrMatrix(Upart, Ppart, 1, 1); divVel = null; // new BlockMsrMatrix(Ppart, Upart, 1, 1); BlockMsrMatrix VelocityMass = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); BlockMsrMatrix leftChangeBasesVel = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); BlockMsrMatrix rightChangeBasesVel = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); op.MassMatrix.AccSubMatrixTo(1.0, VelocityMass, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); op.LeftChangeOfBasis.AccSubMatrixTo(1.0, leftChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); op.RightChangeOfBasis.AccSubMatrixTo(1.0, rightChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); var temp = BlockMsrMatrix.Multiply(leftChangeBasesVel, LocalMatrix); LocalMatrix = BlockMsrMatrix.Multiply(temp, rightChangeBasesVel); var M = op.OperatorMatrix; M.AccSubMatrixTo(1.0, ConvDiff, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); M.AccSubMatrixTo(1.0, pGrad, Uidx, default(int[]), Pidx, default(int[]), default(int[]), default(int[])); M.AccSubMatrixTo(1.0, divVel, Pidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); //LocalMatrix.SaveToTextFileSparse("LocalConvDiffMatrix"); //ConvDiff.SaveToTextFileSparse("ConvDiff"); //op.MassMatrix.SaveToTextFileSparse("MassMatrix"); //VelocityMass.SaveToTextFileSparse("VelocityMass"); }
/// <summary> /// Ctor. /// </summary> /// <param name="LevelSetMapping"></param> /// <param name="Velocity0"></param> /// <param name="Velocity0Mean"></param> /// <param name="SolverConf"></param> public LevelSetAdvectionOperator(UnsetteledCoordinateMapping LevelSetMapping, VectorField <SinglePhaseField> Velocity0, VectorField <SinglePhaseField> Velocity0Mean, SolverConfiguration SolverConf) : base(LevelSetMapping, LevelSetMapping, ArrayTools.Cat <SinglePhaseField>(Velocity0.ToArray(), Velocity0Mean.ToArray()), SolverConf, IsConstant: false) { }
/// <summary> /// Create Spatial Operators and build the corresponding Matrices /// </summary> public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield) { OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength]; //LevelSetTracker.GetLevelSetGradients(0,); // bulk part of the matrix //Operator_bulk.ComputeMatrix( // Extension.Mapping, // LevelSetGradient.ToArray(), // Extension.Mapping, // OpMatrix_bulk, OpAffine_bulk, // OnlyAffine: false, sgrd: null); switch (Control.FluxVariant) { case FluxVariant.GradientBased: // Flux Direction based on Mean Level Set Gradient BulkParams = new List <DGField> { }; // Hack, to make ArrayTools.Cat produce a List of DGFields // second Hack: Does only work, when InterfaceParams is according to a single component flux, // else, we will have to change the boundary edge flux BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray()); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); break; case FluxVariant.ValueBased: // Flux Direction Based on Cell-Averaged Level-Set Value BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet); MeanLevelSet.Clear(); MeanLevelSet.AccLaidBack(1.0, Phi); break; case FluxVariant.SWIP: BulkParams = LevelSetGradient.ToArray(); break; default: throw new Exception(); } // Build Operator Operator_bulk.ComputeMatrixEx(Extension.Mapping, BulkParams, Extension.Mapping, OpMatrix_bulk, OpAffine_bulk, OnlyAffine: false, time: 0.0, edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null), volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null) ); //Operator_interface.ComputeMatrixEx( // LevelSetTracker, // Extension.Mapping, // InterfaceParams, // Extension.Mapping, // OpMatrix_interface, // OpAffine_interface, // OnlyAffine: false, // time: 0, // MPIParameterExchange: false, // whichSpc: LevelSetTracker.GetSpeciesId("A") // ); Operator_interface.OperatorCoefficientsProvider = delegate(LevelSetTracker lstrk, SpeciesId spc, int quadOrder, int TrackerHistoryIdx, double time) { var r = new CoefficientSet() { }; //throw new NotImplementedException("todo"); return(r); }; XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker, Extension.Mapping, InterfaceParams, Extension.Mapping); MultiphaseCellAgglomerator dummy = LevelSetTracker.GetAgglomerator(LevelSetTracker.SpeciesIdS.ToArray(), 2 * Extension.Basis.Degree + 2, 0.0); mtxBuilder.CellLengthScales.Add(LevelSetTracker.GetSpeciesId("A"), dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]); mtxBuilder.time = 0; mtxBuilder.MPITtransceive = false; mtxBuilder.ComputeMatrix(OpMatrix_interface, OpAffine_interface); #if DEBUG OpMatrix_bulk.CheckForNanOrInfM(); OpAffine_bulk.CheckForNanOrInfV(); OpMatrix_interface.CheckForNanOrInfM(); OpAffine_interface.CheckForNanOrInfV(); #endif //Only for Debugging purposes Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0"); Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0"); #if DEBUG //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() ); #endif OpMatrix.Clear(); OpMatrix.Acc(1.0, OpMatrix_bulk); OpMatrix.Acc(1.0, OpMatrix_interface); //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation()); OpMatrix.AssumeSymmetric = false; OpAffine.Clear(); OpAffine.AccV(1.0, OpAffine_bulk); OpAffine.AccV(1.0, OpAffine_interface); #if DEBUG //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest()); #endif }
/// <summary> /// Ctor /// </summary> /// <param name="SpatDim">Spatial dimension (either 2 or 3)</param> /// <param name="NumberOfReactants"></param> /// <param name="BcMap"></param> /// <param name="EoS">Null for multiphase. Has to be given for Low-Mach and combustion to calculate density.</param> /// <param name="idx">Index of scalar in array, </param> /// <param name="Argument">Variable name of the argument (e.g. "Temperature" or "MassFraction0")</param> public LinearizedScalarConvection2Jacobi(int SpatDim, int NumberOfReactants, IncompressibleBoundaryCondMap BcMap, MaterialLaw EoS, int idx) { this.NumberOfReactants = NumberOfReactants; m_SpatialDimension = SpatDim; m_bcmap = BcMap; argumentIndex = m_SpatialDimension + idx; velFunction = new Func <double[], double, double> [GridCommons.FIRST_PERIODIC_BC_TAG, SpatDim]; for (int d = 0; d < SpatDim; d++) { velFunction.SetColumn(m_bcmap.bndFunction[VariableNames.Velocity_d(d)], d); } switch (BcMap.PhysMode) { case PhysicsMode.Multiphase: //this.Argument = VariableNames.LevelSet; m_ArgumentOrdering = new string[] { VariableNames.LevelSet }; break; case PhysicsMode.LowMach: m_ArgumentOrdering = ArrayTools.Cat(VariableNames.VelocityVector(SpatDim), VariableNames.Temperature); // VelocityX,VelocityY,(VelocityZ), Temperature as variables. if (EoS == null) { throw new ApplicationException("EoS has to be given for Low-Mach flows to calculate density."); } else { this.EoS = EoS; } break; case PhysicsMode.MixtureFraction: ; m_ArgumentOrdering = ArrayTools.Cat(VariableNames.VelocityVector(SpatDim), VariableNames.MixtureFraction); // VelocityX,VelocityY,(VelocityZ), MixtureFraction as variables. if (EoS == null) { throw new ApplicationException("EoS has to be given for Low-Mach flows to calculate density."); } else { this.EoS = EoS; } break; case PhysicsMode.Combustion: m_ArgumentOrdering = ArrayTools.Cat(VariableNames.VelocityVector(SpatDim), VariableNames.Temperature, VariableNames.MassFractions(NumberOfReactants - 1)); // u,v,w,T, Y0,Y1,Y2,Y3 as variables (Y4 is calculated as Y4 = 1- (Y0+Y1+Y2+Y3) if (EoS == null) { throw new ApplicationException("EoS has to be given for Low-Mach flows to calculate density."); } else { this.EoS = EoS; } break; default: throw new NotImplementedException(); } }
/// <summary> /// ctor. /// </summary> internal NECQuadratureLevelSet(IGridData context, XSpatialOperatorMk2 DiffOp, V __ResultVector, IList <DGField> __DomainFields, IList <DGField> __Parameters, UnsetteledCoordinateMapping CodomainMap, LevelSetTracker lsTrk, int _iLevSet, Tuple <SpeciesId, SpeciesId> SpeciesPair, ICompositeQuadRule <QuadRule> domAndRule) // : base(new int[] { CodomainMap.MaxTotalNoOfCoordinatesPerCell }, context, domAndRule) // { // ----------------------------------- // set members / check ctor parameters // ----------------------------------- m_lsTrk = lsTrk; this.m_LevSetIdx = _iLevSet; this.m_SpeciesPair = SpeciesPair; this.ResultVector = __ResultVector; m_CodomainMap = CodomainMap; var _Parameters = (__Parameters != null) ? __Parameters.ToArray() : new DGField[0]; if (__DomainFields.Count != DiffOp.DomainVar.Count) { throw new ArgumentException("mismatch between number of domain variables in spatial operator and given domain variables"); } if (_Parameters.Length != DiffOp.ParameterVar.Count) { throw new ArgumentException("mismatch between number of parameter variables in spatial operator and given parameters"); } if (m_CodomainMap.NoOfVariables != DiffOp.CodomainVar.Count) { throw new ArgumentException("mismatch between number of codomain variables in spatial operator and given codomain mapping"); } m_DomainAndParamFields = ArrayTools.Cat(__DomainFields, _Parameters); this.DELTA = __DomainFields.Count; // ------------------------ // sort equation components // ------------------------ int Gamma = m_CodomainMap.NoOfVariables; m_NonlinLsForm_V = DiffOp.GetArgMapping <INonlinLevelSetForm_V>(true, eq => ((eq.LevelSetTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0) && Compfilter(eq), eq => (eq is ILevelSetForm) ? new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq) : null); m_NonlinLsForm_GradV = DiffOp.GetArgMapping <INonlinLevelSetForm_GradV>(true, eq => ((eq.LevelSetTerms & (TermActivationFlags.GradV | TermActivationFlags.UxGradV | TermActivationFlags.GradUxGradV)) != 0) && Compfilter(eq), eq => (eq is ILevelSetForm) ? new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq) : null); m_ValueRequired = new bool[m_DomainAndParamFields.Length]; m_GradientRequired = new bool[m_DomainAndParamFields.Length]; m_NonlinLsForm_V.DetermineReqFields(m_GradientRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); m_NonlinLsForm_GradV.DetermineReqFields(m_GradientRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); m_NonlinLsForm_V.DetermineReqFields(m_ValueRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); m_NonlinLsForm_GradV.DetermineReqFields(m_ValueRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); for (int i = __DomainFields.Count; i < m_DomainAndParamFields.Length; i++) { m_ValueRequired[i] = true; // parameters are always required! } // ----- // alloc // ----- Koeff_V = new MultidimensionalArray[Gamma]; Koeff_GradV = new MultidimensionalArray[Gamma]; for (int gamma = 0; gamma < Gamma; gamma++) { Koeff_V[gamma] = new MultidimensionalArray(3); Koeff_GradV[gamma] = new MultidimensionalArray(4); } int L = m_DomainAndParamFields.Length; m_FieldValuesPos = new MultidimensionalArray[L]; m_FieldValuesNeg = new MultidimensionalArray[L]; m_FieldGradientValuesPos = new MultidimensionalArray[L]; m_FieldGradientValuesNeg = new MultidimensionalArray[L]; for (int l = 0; l < L; l++) { if (m_ValueRequired[l]) { m_FieldValuesPos[l] = new MultidimensionalArray(2); m_FieldValuesNeg[l] = new MultidimensionalArray(2); } if (m_GradientRequired[l]) { m_FieldGradientValuesPos[l] = new MultidimensionalArray(3); m_FieldGradientValuesNeg[l] = new MultidimensionalArray(3); } } // ------------------ // init custom timers // ------------------ base.CustomTimers = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() }; base.CustomTimers_Names = new string[] { "Flux-Eval", "Basis-Eval", "Loops", "ParametersAndNormals", "Field-Eval" }; base.CustomTimers_RootPointer = new int[5]; ArrayTools.SetAll(base.CustomTimers_RootPointer, -1); this.m_NonlinLsForm_V_Watches = this.m_NonlinLsForm_V.InitStopWatches(0, this); this.m_NonlinLsForm_GradV_Watches = this.m_NonlinLsForm_GradV.InitStopWatches(0, this); Flux_Eval = base.CustomTimers[0]; Basis_Eval = base.CustomTimers[1]; Loops = base.CustomTimers[2]; ParametersAndNormals = base.CustomTimers[3]; Field_Eval = base.CustomTimers[4]; }
/// <summary> /// Usual plotting /// </summary> protected override void PlotCurrentState(double physTime, TimestepNumber timestepNo, int superSampling = 0) { Tecplot.PlotFields( ArrayTools.Cat <DGField>(f1Gradient_Analytical, f1Gradient_Numerical, f1, GridData.BoundaryMark(), Laplace_f1_Numerical, Laplace_f2_Numerical), "derivatives", 0.0, superSampling); }
/// <summary> /// ctor. /// </summary> internal NECQuadratureLevelSet(IGridData context, XSpatialOperatorMk2 DiffOp, V __ResultVector, IList <DGField> __DomainFields, IList <DGField> __Parameters, UnsetteledCoordinateMapping CodomainMap, LevelSetTracker lsTrk, int _iLevSet, Tuple <SpeciesId, SpeciesId> SpeciesPair, ICompositeQuadRule <QuadRule> domAndRule) // : base(new int[] { CodomainMap.GetNonXBasisLengths(0).Sum() * 2 }, // we always integrate over species in pairs (neg + pos), so we need to alloc mem only 2 species context, domAndRule) // { MPICollectiveWatchDog.Watch(); // ----------------------------------- // set members / check ctor parameters // ----------------------------------- m_lsTrk = lsTrk; this.m_LevSetIdx = _iLevSet; this.m_SpeciesPair = SpeciesPair; this.ResultVector = __ResultVector; m_CodomainMap = CodomainMap; var _Parameters = (__Parameters != null) ? __Parameters.ToArray() : new DGField[0]; if (__DomainFields.Count != DiffOp.DomainVar.Count) { throw new ArgumentException("mismatch between number of domain variables in spatial operator and given domain variables"); } if (_Parameters.Length != DiffOp.ParameterVar.Count) { throw new ArgumentException("mismatch between number of parameter variables in spatial operator and given parameters"); } if (m_CodomainMap.NoOfVariables != DiffOp.CodomainVar.Count) { throw new ArgumentException("mismatch between number of codomain variables in spatial operator and given codomain mapping"); } var _DomainAndParamFields = ArrayTools.Cat(__DomainFields, _Parameters); this.DELTA = __DomainFields.Count; m_DomainAndParamFieldsA = new ConventionalDGField[_DomainAndParamFields.Length]; m_DomainAndParamFieldsB = new ConventionalDGField[_DomainAndParamFields.Length]; for (int i = 0; i < m_DomainAndParamFieldsA.Length; i++) { var f = _DomainAndParamFields[i]; if (f == null) { m_DomainAndParamFieldsA[i] = null; m_DomainAndParamFieldsB[i] = null; } else if (f is XDGField xf) { m_DomainAndParamFieldsA[i] = xf.GetSpeciesShadowField(this.SpeciesA); m_DomainAndParamFieldsB[i] = xf.GetSpeciesShadowField(this.SpeciesB); } else if (f is ConventionalDGField cf) { m_DomainAndParamFieldsA[i] = cf; m_DomainAndParamFieldsB[i] = null; } else { throw new NotImplementedException("missing implementation for " + f.GetType().Name); } } LECQuadratureLevelSet <IMutableMatrix, double[]> .TestNegativeAndPositiveSpecies(domAndRule, m_lsTrk, SpeciesA, SpeciesB, m_LevSetIdx); // ------------------------ // sort equation components // ------------------------ int Gamma = m_CodomainMap.NoOfVariables; m_NonlinLsForm_V = EquationComponentArgMapping <INonlinLevelSetForm_V> .GetArgMapping(DiffOp, true, eq => ((eq.LevelSetTerms & (TermActivationFlags.V | TermActivationFlags.UxV | TermActivationFlags.GradUxV)) != 0) && Compfilter(eq), eq => (eq is ILevelSetForm)?new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq, lsTrk) : null); m_NonlinLsForm_GradV = EquationComponentArgMapping <INonlinLevelSetForm_GradV> .GetArgMapping(DiffOp, true, eq => ((eq.LevelSetTerms & (TermActivationFlags.GradV | TermActivationFlags.UxGradV | TermActivationFlags.GradUxGradV)) != 0) && Compfilter(eq), eq => (eq is ILevelSetForm)?new NonlinearLevelSetFormVectorizer((ILevelSetForm)eq, lsTrk) : null); m_ValueRequired = new bool[m_DomainAndParamFieldsA.Length]; m_GradientRequired = new bool[m_DomainAndParamFieldsA.Length]; m_NonlinLsForm_V.DetermineReqFields(m_GradientRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); m_NonlinLsForm_GradV.DetermineReqFields(m_GradientRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.GradUxGradV | TermActivationFlags.GradUxV)) != 0)); m_NonlinLsForm_V.DetermineReqFields(m_ValueRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); m_NonlinLsForm_GradV.DetermineReqFields(m_ValueRequired, comp => ((comp.LevelSetTerms & (TermActivationFlags.UxGradV | TermActivationFlags.UxV)) != 0)); for (int i = __DomainFields.Count; i < m_DomainAndParamFieldsA.Length; i++) { m_ValueRequired[i] = true; // parameters are always required! } // ----- // alloc // ----- Koeff_V = new MultidimensionalArray[Gamma]; Koeff_GradV = new MultidimensionalArray[Gamma]; for (int gamma = 0; gamma < Gamma; gamma++) { Koeff_V[gamma] = new MultidimensionalArray(3); Koeff_GradV[gamma] = new MultidimensionalArray(4); } Debug.Assert(m_DomainAndParamFieldsA.Length == m_DomainAndParamFieldsB.Length); int L = m_DomainAndParamFieldsA.Length; m_FieldValuesPos = new MultidimensionalArray[L]; m_FieldValuesNeg = new MultidimensionalArray[L]; m_FieldGradientValuesPos = new MultidimensionalArray[L]; m_FieldGradientValuesNeg = new MultidimensionalArray[L]; for (int l = 0; l < L; l++) { if (m_ValueRequired[l]) { m_FieldValuesPos[l] = new MultidimensionalArray(2); m_FieldValuesNeg[l] = new MultidimensionalArray(2); } if (m_GradientRequired[l]) { m_FieldGradientValuesPos[l] = new MultidimensionalArray(3); m_FieldGradientValuesNeg[l] = new MultidimensionalArray(3); } } // ------------------ // init custom timers // ------------------ base.CustomTimers = new Stopwatch[] { new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch(), new Stopwatch() }; base.CustomTimers_Names = new string[] { "Flux-Eval", "Basis-Eval", "Loops", "ParametersAndNormals", "Field-Eval" }; base.CustomTimers_RootPointer = new int[5]; ArrayTools.SetAll(base.CustomTimers_RootPointer, -1); this.m_NonlinLsForm_V_Watches = this.m_NonlinLsForm_V.InitStopWatches(0, this); this.m_NonlinLsForm_GradV_Watches = this.m_NonlinLsForm_GradV.InitStopWatches(0, this); Flux_Eval = base.CustomTimers[0]; Basis_Eval = base.CustomTimers[1]; Loops = base.CustomTimers[2]; ParametersAndNormals = base.CustomTimers[3]; Field_Eval = base.CustomTimers[4]; }
/// <summary> /// Create Spatial Operators and build the corresponding Matrices /// </summary> public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield) { OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength]; //LevelSetTracker.GetLevelSetGradients(0,); // bulk part of the matrix //Operator_bulk.ComputeMatrix( // Extension.Mapping, // LevelSetGradient.ToArray(), // Extension.Mapping, // OpMatrix_bulk, OpAffine_bulk, // OnlyAffine: false, sgrd: null); switch (Control.FluxVariant) { case FluxVariant.GradientBased: // Flux Direction based on Mean Level Set Gradient BulkParams = new List <DGField> { }; // Hack, to make ArrayTools.Cat produce a List of DGFields // second Hack: Does only work, when InterfaceParams is according to a single component flux, // else, we will have to change the boundary edge flux BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray()); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); break; case FluxVariant.ValueBased: // Flux Direction Based on Cell-Averaged Level-Set Value BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet); MeanLevelSet.Clear(); MeanLevelSet.AccLaidBack(1.0, Phi); break; case FluxVariant.SWIP: BulkParams = LevelSetGradient.ToArray(); break; default: throw new Exception(); } // Build Operator Operator_bulk.ComputeMatrixEx(Extension.Mapping, BulkParams, Extension.Mapping, OpMatrix_bulk, OpAffine_bulk, OnlyAffine: false, time: 0.0, edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null), volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null) ); Operator_interface.ComputeMatrixEx( LevelSetTracker, Extension.Mapping, InterfaceParams, Extension.Mapping, OpMatrix_interface, OpAffine_interface, OnlyAffine: false, time: 0, MPIParameterExchange: false, whichSpc: LevelSetTracker.GetSpeciesId("A") ); #if DEBUG OpMatrix_bulk.CheckForNanOrInfM(); OpAffine_bulk.CheckForNanOrInfV(); OpMatrix_interface.CheckForNanOrInfM(); OpAffine_interface.CheckForNanOrInfV(); #endif //Only for Debugging purposes //OpMatrix.SaveToTextFileSparse("C:\\tmp\\EllipticReInit.txt"); Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0"); Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0"); #if DEBUG //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() ); #endif OpMatrix.Clear(); OpMatrix.Acc(1.0, OpMatrix_bulk); OpMatrix.Acc(1.0, OpMatrix_interface); //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation()); OpMatrix.AssumeSymmetric = false; OpAffine.Clear(); OpAffine.AccV(1.0, OpAffine_bulk); OpAffine.AccV(1.0, OpAffine_interface); #if DEBUG //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest()); #endif }
/// <summary> /// /// </summary> public void AssembleMatrix_Timestepper <T>( int CutCellQuadOrder, BlockMsrMatrix OpMatrix, double[] OpAffine, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, IEnumerable <T> U0, VectorField <SinglePhaseField> SurfaceForce, VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, double time) where T : DGField { if (ColMapping.BasisS.Count != this.Op.DomainVar.Count) { throw new ArgumentException(); } if (RowMapping.BasisS.Count != this.Op.CodomainVar.Count) { throw new ArgumentException(); } // check: var Tracker = this.LsTrk; int D = Tracker.GridDat.SpatialDimension; if (U0 != null && U0.Count() != D) { throw new ArgumentException(); } LevelSet Phi = (LevelSet)(Tracker.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); // parameter assembly // ================== // normals: SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions. if (this.NormalsRequired) { if (LevelSetGradient == null) { LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory); LevelSetGradient.Gradient(1.0, Phi); } Normals = LevelSetGradient.ToArray(); } else { Normals = new SinglePhaseField[D]; } // curvature: SinglePhaseField Curvature; if (this.CurvatureRequired) { Curvature = ExternalyProvidedCurvature; } else { Curvature = null; } // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(Tracker, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); } else { U0_U0mean = new DGField[2 * D]; } // concatenate everything var Params = ArrayTools.Cat <DGField>( U0_U0mean, Curvature, ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]), Normals); // linearization velocity: if (this.U0meanrequired) { VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray()); U0mean.Clear(); if (this.physParams.IncludeConvection) { ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } } // assemble the matrix & affine vector // =================================== // compute matrix Op.ComputeMatrixEx(Tracker, ColMapping, Params, RowMapping, OpMatrix, OpAffine, false, time, true, AgglomeratedCellLengthScales, SpcToCompute); }
/// <summary> /// /// </summary> public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time, int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce, VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature, bool[] updateSolutionParams = null, DGField[] ExtParams = null) where T : DGField { //IEnumerable<T> CoupledCurrentState = null, IEnumerable<T> CoupledParams = null) where T : DGField { // checks: if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count) { throw new ArgumentException(); } if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count) { throw new ArgumentException(); } int D = this.LsTrk.GridDat.SpatialDimension; if (CurrentState != null && !config.solveEnergy && !config.solveHeat && CurrentState.Count() != (D + 1)) { throw new ArgumentException(); } if (OpMatrix == null && CurrentState == null) { throw new ArgumentException(); } DGField[] U0; if (CurrentState != null) { U0 = CurrentState.Take(D).ToArray(); } else { U0 = null; } // parameter assembly // ================== #region param assembly LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(this.LsTrk, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0mean.Clear(); if (this.physParams.IncludeConvection) { ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); } else { U0_U0mean = new DGField[2 * D]; } // linearization velocity: //if (this.U0meanrequired) { // VectorField<XDGField> U0mean = new VectorField<XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray()); // U0mean.Clear(); // if (this.physParams.IncludeConvection) // ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); //} // normals: SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions. if (this.NormalsRequired) { if (LevelSetGradient == null) { LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory); LevelSetGradient.Gradient(1.0, Phi); } Normals = LevelSetGradient.ToArray(); } else { Normals = new SinglePhaseField[D]; } // curvature: SinglePhaseField Curvature; if (this.CurvatureRequired) { Curvature = ExternalyProvidedCurvature; } else { Curvature = null; } // velocity gradient vectors var VelMap = new CoordinateMapping(U0); DGField[] VelParam = VelMap.Fields.ToArray(); VectorField <DGField> GradVelX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradient", XDGField.Factory); for (int d = 0; d < D; d++) { foreach (var Spc in this.LsTrk.SpeciesIdS) { DGField f_Spc = ((VelParam[0] as XDGField).GetSpeciesShadowField(Spc)); SubGrid sf = this.LsTrk.Regions.GetSpeciesSubGrid(Spc); (GradVelX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf); } } GradVelX.ForEach(F => F.CheckForNanOrInf(true, true, true)); VectorField <DGField> GradVelY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradient", XDGField.Factory); for (int d = 0; d < D; d++) { foreach (var Spc in this.LsTrk.SpeciesIdS) { DGField f_Spc = ((VelParam[1] as XDGField).GetSpeciesShadowField(Spc)); SubGrid sf = this.LsTrk.Regions.GetSpeciesSubGrid(Spc); (GradVelY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf); } } GradVelY.ForEach(F => F.CheckForNanOrInf(true, true, true)); VectorField <DGField> GradVelXGradX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradX_Gradient", XDGField.Factory); for (int d = 0; d < D; d++) { foreach (var Spc in this.LsTrk.SpeciesIdS) { DGField f_Spc = ((GradVelX[0] as XDGField).GetSpeciesShadowField(Spc)); SubGrid sf = this.LsTrk.Regions.GetSpeciesSubGrid(Spc); (GradVelXGradX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf); } } GradVelXGradX.ForEach(F => F.CheckForNanOrInf(true, true, true)); VectorField <DGField> GradVelXGradY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityXGradY_Gradient", XDGField.Factory); for (int d = 0; d < D; d++) { foreach (var Spc in this.LsTrk.SpeciesIdS) { DGField f_Spc = ((GradVelX[1] as XDGField).GetSpeciesShadowField(Spc)); SubGrid sf = this.LsTrk.Regions.GetSpeciesSubGrid(Spc); (GradVelXGradY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf); } } GradVelXGradY.ForEach(F => F.CheckForNanOrInf(true, true, true)); VectorField <DGField> GradVelYGradX = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradX_Gradient", XDGField.Factory); for (int d = 0; d < D; d++) { foreach (var Spc in this.LsTrk.SpeciesIdS) { DGField f_Spc = ((GradVelY[0] as XDGField).GetSpeciesShadowField(Spc)); SubGrid sf = this.LsTrk.Regions.GetSpeciesSubGrid(Spc); (GradVelYGradX[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf); } } GradVelYGradX.ForEach(F => F.CheckForNanOrInf(true, true, true)); VectorField <DGField> GradVelYGradY = new VectorField <DGField>(D, VelParam[0].Basis, "VelocityYGradY_Gradient", XDGField.Factory); for (int d = 0; d < D; d++) { foreach (var Spc in this.LsTrk.SpeciesIdS) { DGField f_Spc = ((GradVelY[1] as XDGField).GetSpeciesShadowField(Spc)); SubGrid sf = this.LsTrk.Regions.GetSpeciesSubGrid(Spc); (GradVelYGradY[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf); } } GradVelYGradY.ForEach(F => F.CheckForNanOrInf(true, true, true)); // pressure and gradient var PressMap = new CoordinateMapping(CurrentState.ToArray()[D]); DGField[] PressParam = PressMap.Fields.ToArray(); VectorField <DGField> PressGrad = new VectorField <DGField>(D, PressParam[0].Basis, "PressureGrad", XDGField.Factory); for (int d = 0; d < D; d++) { foreach (var Spc in this.LsTrk.SpeciesIdS) { DGField f_Spc = ((PressParam[0] as XDGField).GetSpeciesShadowField(Spc)); SubGrid sf = this.LsTrk.Regions.GetSpeciesSubGrid(Spc); (PressGrad[d] as XDGField).GetSpeciesShadowField(Spc).DerivativeByFlux(1.0, f_Spc, d, optionalSubGrid: sf); } } PressGrad.ForEach(F => F.CheckForNanOrInf(true, true, true)); // gravity var GravMap = new CoordinateMapping(ExtParams); DGField[] GravParam = GravMap.Fields.ToArray(); // heat flux for evaporation DGField[] HeatFluxParam = new DGField[D]; if (config.solveHeat) { if (config.conductMode == ConductivityInSpeciesBulk.ConductivityMode.SIP && updateSolutionParams[D + 1]) { HeatFluxParam = new VectorField <XDGField>(D, CurrentState.ToArray()[D + 1].Basis, "HeatFlux0_", XDGField.Factory).ToArray(); Dictionary <string, double> kSpc = new Dictionary <string, double>(); kSpc.Add("A", -thermParams.k_A); kSpc.Add("B", -thermParams.k_B); XNSEUtils.ComputeGradientForParam(CurrentState.ToArray()[D + 1], HeatFluxParam, this.LsTrk, kSpc, this.LsTrk.Regions.GetCutCellSubGrid()); } else if (config.conductMode != ConductivityInSpeciesBulk.ConductivityMode.SIP && updateSolutionParams[D + 2]) { var HeatFluxMap = new CoordinateMapping(CurrentState.ToArray().GetSubVector(D + 2, D)); HeatFluxParam = HeatFluxMap.Fields.ToArray(); } else { HeatFluxParam = storedParams.GetSubVector(2 * D + 4, D); } } if (ExtParams != null) { HeatFluxParam = ExtParams; } #endregion // concatenate everything var Params = ArrayTools.Cat <DGField>( U0_U0mean, Normals, Curvature, ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D])); if (config.solveEnergy) { Params = ArrayTools.Cat <DGField>(Params.ToArray <DGField>(), GradVelX, GradVelY, GradVelXGradX, GradVelXGradY, GradVelYGradX, GradVelYGradY, PressParam, PressGrad, GravMap); } if (config.solveHeat) { Params = ArrayTools.Cat <DGField>(Params.ToArray <DGField>(), CurrentState.ToArray <DGField>().GetSubVector(D + 1, 1), HeatFluxParam, new SinglePhaseField[1]); } // store old params for (int p = 0; p < Params.Length; p++) { if (Params[p] != null) { storedParams[p] = Params[p].CloneAs(); } } // advanced settings for the navier slip boundary condition // ======================================================== CellMask SlipArea; switch (this.dntParams.GNBC_Localization) { case NavierSlip_Localization.Bulk: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask; break; } case NavierSlip_Localization.ContactLine: { SlipArea = null; break; } case NavierSlip_Localization.Nearband: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth)); break; } case NavierSlip_Localization.Prescribed: { throw new NotImplementedException(); } default: throw new ArgumentException(); } MultidimensionalArray SlipLengths; SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs(); SlipLengths.Clear(); //SlipLengths.AccConstant(-1.0); if (SlipArea != null) { foreach (Chunk cnk in SlipArea) { for (int i = cnk.i0; i < cnk.JE; i++) { switch (this.dntParams.GNBC_SlipLength) { case NavierSlip_SlipLength.hmin_DG: { int degU = ColMapping.BasisS.ToArray()[0].Degree; SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1); break; } case NavierSlip_SlipLength.hmin_Grid: { SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i]; break; } case NavierSlip_SlipLength.Prescribed_SlipLength: { SlipLengths[i] = this.physParams.sliplength; break; } case NavierSlip_SlipLength.Prescribed_Beta: { SlipLengths[i] = -1.0; break; } } } } } // interface coefficients // ====================== MultidimensionalArray lambdaI, muI; lambdaI = SlipLengths.CloneAs(); lambdaI.Clear(); muI = SlipLengths.CloneAs(); muI.Clear(); foreach (Chunk cnk in this.LsTrk.Regions.GetCutCellMask()) { for (int i = cnk.i0; i < cnk.JE; i++) { double lI = 0.0; double mI = 0.0; // do the magic!!! if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] > 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] > 0) { } if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] > 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] < 0) { //lI = config.physParams.Sigma; mI = config.physParams.Sigma; } if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] < 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] < 0) { //lI = -config.physParams.Sigma; mI = -config.physParams.Sigma; } if (this.LsTrk.GridDat.Cells.CellCenter[i, 0] < 0 && this.LsTrk.GridDat.Cells.CellCenter[i, 1] > 0) { //lI = 10 * config.physParams.Sigma; mI = 10 * config.physParams.Sigma; } lambdaI[i] = lI; muI[i] = mI; } } // assemble the matrix & affine vector // =================================== IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea; BitArray EvapMicroRegion = this.LsTrk.GridDat.GetBoundaryCells().GetBitMask(); EvapMicroRegion.SetAll(false); // compute matrix if (OpMatrix != null) { XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping); foreach (var kv in AgglomeratedCellLengthScales) { mtxBuilder.CellLengthScales[kv.Key] = kv.Value; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["SlipLengths"] = SlipLengths; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["EvapMicroRegion"] = EvapMicroRegion; if (config.prescribedMassflux != null) { double[] dummyX = new double[] { 0.0, 0.0 }; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["prescribedMassflux"] = config.prescribedMassflux(dummyX, time); } } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["InterfaceLengths"] = kv.Value; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["lambda_interface"] = lambdaI; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["mu_interface"] = muI; } } mtxBuilder.time = time; mtxBuilder.ComputeMatrix(OpMatrix, OpAffine); } else { XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk, CurrentState.ToArray(), Params, RowMapping); foreach (var kv in AgglomeratedCellLengthScales) { eval.CellLengthScales[kv.Key] = kv.Value; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["SlipLengths"] = SlipLengths; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["EvapMicroRegion"] = EvapMicroRegion; if (config.prescribedMassflux != null) { double[] dummyX = new double[] { 0.0, 0.0 }; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["prescribedMassflux"] = config.prescribedMassflux(dummyX, time); } } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["InterfaceLengths"] = kv.Value; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["lambda_interface"] = lambdaI; this.m_XOp.UserDefinedValues[this.LsTrk.GetSpeciesName(kv.Key)]["mu_interface"] = muI; } } eval.time = time; eval.Evaluate(1.0, 1.0, OpAffine); } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="OpMatrix"></param> /// <param name="OpAffine"></param> /// <param name="RowMapping"></param> /// <param name="ColMapping"></param> /// <param name="CurrentState"></param> /// <param name="AgglomeratedCellLengthScales"></param> /// <param name="time"></param> /// <param name="CutCellQuadOrder"></param> /// <param name="SurfaceForce"></param> /// <param name="LevelSetGradient"></param> /// <param name="ExternalyProvidedCurvature"></param> public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time, int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce, VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature, double currentWeissenberg, IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField { // checks: if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count) { throw new ArgumentException(); } if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count) { throw new ArgumentException(); } int D = this.LsTrk.GridDat.SpatialDimension; if (CurrentState != null && CurrentState.Count() != (D + 4)) { throw new ArgumentException(); } if (OpMatrix == null && CurrentState == null) { throw new ArgumentException(); } DGField[] U0; if (CurrentState != null) { U0 = CurrentState.Take(D).ToArray(); } else { U0 = null; } DGField[] Stress0; Stress0 = CurrentState.Skip(D + 1).Take(3).ToArray(); if (U0.Count() != D) { throw new ArgumentException("Spatial dimesion and number of velocity parameter components does not match!"); } if (Stress0.Count() != D + 1) { throw new ArgumentException("Spatial dimesion and number of stress parameter components does not match!"); } // advanced settings for the navier slip boundary condition // ======================================================== CellMask SlipArea; switch (this.dntParams.GNBC_Localization) { case NavierSlip_Localization.Bulk: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask; break; } case NavierSlip_Localization.ContactLine: { SlipArea = null; break; } case NavierSlip_Localization.Nearband: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth)); break; } case NavierSlip_Localization.Prescribed: { throw new NotImplementedException(); } default: throw new ArgumentException(); } MultidimensionalArray SlipLengths; SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs(); SlipLengths.Clear(); //SlipLengths.AccConstant(-1.0); if (SlipArea != null) { foreach (Chunk cnk in SlipArea) { for (int i = cnk.i0; i < cnk.JE; i++) { switch (this.dntParams.GNBC_SlipLength) { case NavierSlip_SlipLength.hmin_DG: { int degU = ColMapping.BasisS.ToArray()[0].Degree; SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1); break; } case NavierSlip_SlipLength.hmin_Grid: { SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i]; break; } case NavierSlip_SlipLength.Prescribed_SlipLength: { SlipLengths[i] = this.physParams.sliplength; break; } case NavierSlip_SlipLength.Prescribed_Beta: { SlipLengths[i] = -1.0; break; } } } } } // parameter assembly // ================== LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); // normals: SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions. if (this.NormalsRequired) { if (LevelSetGradient == null) { LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory); LevelSetGradient.Gradient(1.0, Phi); } Normals = LevelSetGradient.ToArray(); } else { Normals = new SinglePhaseField[D]; } // curvature: SinglePhaseField Curvature; if (this.CurvatureRequired) { Curvature = ExternalyProvidedCurvature; } else { Curvature = null; } // Velocity and stresses for linearization // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(this.LsTrk, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); } else { U0_U0mean = new DGField[2 * D]; } if (VelocityXGradient == null) { VelocityXGradient = new VectorField <XDGField>(D, CurrentState.ElementAt(0).Basis, "VelocityX_Gradient", XDGField.Factory); } if (VelocityYGradient == null) { VelocityYGradient = new VectorField <XDGField>(D, CurrentState.ElementAt(1).Basis, "VelocityY_Gradient", XDGField.Factory); } // concatenate everything var Params = ArrayTools.Cat <DGField>( U0_U0mean, VelocityXGradient, VelocityYGradient, Stress0, //artificalViscosity, Normals, Curvature, ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D])); // linearization velocity: if (this.U0meanrequired) { VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray()); U0mean.Clear(); if (this.physParams.IncludeConvection) { ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } } // assemble the matrix & affine vector // =================================== IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea; BitArray EvapMicroRegion = this.LsTrk.GridDat.GetBoundaryCells().GetBitMask(); EvapMicroRegion.SetAll(false); // compute matrix if (OpMatrix != null) { if (!useJacobianForOperatorMatrix) { XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute); this.ParameterUpdate(CurrentState, Params, CutCellQuadOrder, AgglomeratedCellLengthScales); foreach (var kv in AgglomeratedCellLengthScales) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; mtxBuilder.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = this.LsTrk.GridDat.Edges.h_max_Edge; mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion); } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } mtxBuilder.time = time; mtxBuilder.ComputeMatrix(OpMatrix, OpAffine); foreach (var kv in AgglomeratedCellLengthScales) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg); } } else { throw new NotImplementedException("The FDbuilder for the Jacobian is missing for the XSpatial Opearator!"); // Finite Difference Linearization //XSpatialOperatorMk2.XEvaluatorLinear FDBuilder = this.m_XOp.GetFDJacobianBuilder(domMap, Params, codMap, this.ParameterUpdate); //foreach (var kv in AgglomeratedCellLengthScales) { // FDbuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; // FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); // FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion); //} //if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { // foreach (var kv in InterfaceLengths) { // FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); // } //} //FDbuilder.time = time; //FDbuilder.ComputeMatrix(OpMatrix, OpAffine); //// FDJacobian has (Mx +b) as RHS, for unsteady calc. we must subtract Mx for real affine Vector! //OpMatrix.SpMV(-1.0, new CoordinateVector(CurrentState), 1.0, OpAffine); //foreach (var kv in AgglomeratedCellLengthScales) { // FDbuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg); //} } } else { XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk, CurrentState.ToArray(), Params, RowMapping, SpcToCompute); foreach (var kv in AgglomeratedCellLengthScales) { eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = this.LsTrk.GridDat.Edges.h_max_Edge; eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion); eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("Weissenbergnumber", currentWeissenberg); } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } eval.time = time; eval.Evaluate(1.0, 1.0, OpAffine); } }
public static IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0) { IBM_Control C = new IBM_Control(); const double BaseSize = 1.0; // basic database options // ==================== C.savetodb = false; C.ProjectDescription = "Cylinder"; C.Tags.Add("with immersed boundary method"); // DG degrees // ========== C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = k - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); // grid and boundary conditions // ============================ C.GridFunc = delegate { var _xNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1, false); _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1)); var _xNodes2 = GenericBlas.Linspace(1, 5.5, 35); _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1)); var _xNodes3 = Grid1D.TanhSpacing(5.5, 22, 20, 1.3, true); var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3); var _yNodes1 = Grid1D.TanhSpacing(0, 1, 5, 1.2, false); _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = GenericBlas.Linspace(1, 3, 20); _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); var _yNodes3 = Grid1D.TanhSpacing(3, 4.1, 5, 1.2, true); var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic); grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); if (!xPeriodic) { grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); } grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] - (0 * BaseSize)) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] + (-4.1 * BaseSize)) <= 1.0e-8) { et = 2; } if (!xPeriodic && Math.Abs(X[0] - (0 * BaseSize)) <= 1.0e-8) { et = 3; } if (!xPeriodic && Math.Abs(X[0] + (-22 * BaseSize)) <= 1.0e-8) { et = 4; } Debug.Assert(et != 0); return(et); }); return(grd); }; C.AddBoundaryValue("Velocity_Inlet_upper", "VelocityX", X => 0); C.AddBoundaryValue("Velocity_Inlet_lower", "VelocityX", X => 0); if (!xPeriodic) { C.AddBoundaryValue("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1))); } C.AddBoundaryValue("Pressure_Outlet_right"); // Initial Values // ============== C.particleRadius = 0.5; C.InitialValues_Evaluators.Add("Phi", X => - (X[0] - 2).Pow2() + -(X[1] - 2).Pow2() + C.particleRadius.Pow2()); C.InitialValues_Evaluators.Add("VelocityX", X => 0); // Physical Parameters // =================== C.PhysicalParameters.mu_A = 0.05; C.PhysicalParameters.rho_A = 1; C.PhysicalParameters.IncludeConvection = true; C.PhysicalParameters.Material = true; // misc. solver options // ==================== C.AdvancedDiscretizationOptions.PenaltySafety = 1; C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.1; C.LevelSetSmoothing = false; C.MaxKrylovDim = 20; C.MaxSolverIterations = 100; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite; C.NoOfMultigridLevels = 1; // Timestepping // ============ C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2; double dt = 1E20; C.dtFixed = dt; C.dtMax = dt; C.dtMin = dt; C.Endtime = 200; C.NoOfTimesteps = 1; // haben fertig... // =============== return(C); }
void ParameterUpdate(IEnumerable <DGField> CurrentState, IEnumerable <DGField> ParameterVar, int CutCellQuadOrder, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales) { LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); DGField[] U0; if (CurrentState != null) { U0 = CurrentState.Take(D).ToArray(); } else { U0 = null; } DGField[] Stress0; Stress0 = CurrentState.Skip(D + 1).Take(3).ToArray(); if (U0.Count() != D) { throw new ArgumentException("Spatial dimesion and number of velocity parameter components does not match!"); } if (Stress0.Count() != D + 1) { throw new ArgumentException("Spatial dimesion and number of stress parameter components does not match!"); } // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(this.LsTrk, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); U0mean.Clear(); ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } else { U0_U0mean = new DGField[2 * D]; } //if (this.Control.SetParamsAnalyticalSol == false) { //SinglePhaseField[] __VelocityXGradient = ParameterVar.Skip(2 * D).Take(D).Select(f => f as SinglePhaseField).ToArray(); //SinglePhaseField[] __VelocityYGradient = ParameterVar.Skip(3 * D).Take(D).Select(f => f as SinglePhaseField).ToArray(); //Debug.Assert(ArrayTools.AreEqual(__VelocityXGradient, VelocityXGradient.ToArray(), (fa, fb) => object.ReferenceEquals(fa, fb))); //Debug.Assert(ArrayTools.AreEqual(__VelocityYGradient, VelocityYGradient.ToArray(), (fa, fb) => object.ReferenceEquals(fa, fb))); //if (VelocityXGradient == null) { // VelocityXGradient = new VectorField<XDGField>(D, CurrentState.ElementAt(0).Basis, "VelocityX_Gradient", XDGField.Factory); //} VelocityXGradient.Clear(); VelocityXGradient.GradientByFlux(1.0, U0[0]); //if (VelocityYGradient == null) { // VelocityYGradient = new VectorField<XDGField>(D, CurrentState.ElementAt(1).Basis, "VelocityY_Gradient", XDGField.Factory); //} VelocityYGradient.Clear(); VelocityYGradient.GradientByFlux(1.0, U0[1]); //} if (this.useArtificialDiffusion == true) { throw new NotImplementedException("artificial diffusion not jet fully implemented..."); //SinglePhaseField __ArtificialViscosity = ParameterVar.Skip(5 * D + 1).Take(1).Select(f => f as SinglePhaseField).ToArray()[0]; //if (!object.ReferenceEquals(this.artificalViscosity, __ArtificialViscosity)) // throw new ApplicationException(); //ArtificialViscosity.ProjectArtificalViscosityToDGField(__ArtificialViscosity, perssonsensor, this.Control.SensorLimit, artificialMaxViscosity); } }
/// <summary> /// /// </summary> public void AssembleMatrix_Timestepper <T>( int CutCellQuadOrder, BlockMsrMatrix OpMatrix, double[] OpAffine, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, IEnumerable <T> CurrentState, VectorField <SinglePhaseField> SurfaceForce, VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, double time, IEnumerable <T> CoupledCurrentState = null, IEnumerable <T> CoupledParams = null) where T : DGField { if (ColMapping.BasisS.Count != this.Op.DomainVar.Count) { throw new ArgumentException(); } if (RowMapping.BasisS.Count != this.Op.CodomainVar.Count) { throw new ArgumentException(); } // check: var Tracker = this.LsTrk; int D = Tracker.GridDat.SpatialDimension; if (CurrentState != null && CurrentState.Count() != (D + 1)) { throw new ArgumentException(); } if (OpMatrix == null && CurrentState == null) { throw new ArgumentException(); } DGField[] U0; if (CurrentState != null) { U0 = CurrentState.Take(D).ToArray(); } else { U0 = null; } LevelSet Phi = (LevelSet)(Tracker.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea; // advanced settings for the navier slip boundary condition // ======================================================== CellMask SlipArea; switch (this.dntParams.GNBC_Localization) { case NavierSlip_Localization.Bulk: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask; break; } case NavierSlip_Localization.ContactLine: { SlipArea = null; break; } case NavierSlip_Localization.Nearband: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth)); break; } case NavierSlip_Localization.Prescribed: { throw new NotImplementedException(); } default: throw new ArgumentException(); } MultidimensionalArray SlipLengths; SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs(); SlipLengths.Clear(); //SlipLengths.AccConstant(-1.0); if (SlipArea != null) { foreach (Chunk cnk in SlipArea) { for (int i = cnk.i0; i < cnk.JE; i++) { switch (this.dntParams.GNBC_SlipLength) { case NavierSlip_SlipLength.hmin_DG: { int degU = ColMapping.BasisS.ToArray()[0].Degree; SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1); break; } case NavierSlip_SlipLength.hmin_Grid: { SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i]; break; } case NavierSlip_SlipLength.Prescribed_SlipLength: { SlipLengths[i] = this.physParams.sliplength; break; } case NavierSlip_SlipLength.Prescribed_Beta: { SlipLengths[i] = -1.0; break; } } } } } // parameter assembly // ================== // normals: SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions. if (this.NormalsRequired) { if (LevelSetGradient == null) { LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory); LevelSetGradient.Gradient(1.0, Phi); } Normals = LevelSetGradient.ToArray(); } else { Normals = new SinglePhaseField[D]; } // curvature: SinglePhaseField Curvature; if (this.CurvatureRequired) { Curvature = ExternalyProvidedCurvature; } else { Curvature = null; } // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(Tracker, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); } else { U0_U0mean = new DGField[2 * D]; } // Temperature gradient for evaporation VectorField <DGField> GradTemp = new VectorField <DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory); if (CoupledCurrentState != null) { DGField Temp = CoupledCurrentState.ToArray()[0]; GradTemp = new VectorField <DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory); XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk); } // concatenate everything var Params = ArrayTools.Cat <DGField>( U0_U0mean, Curvature, ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D]), Normals, ((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D]), ((evaporation) ? CoupledCurrentState.ToArray <DGField>() : new SinglePhaseField[1]), ((evaporation) ? CoupledParams.ToArray <DGField>() : new SinglePhaseField[1])); //((evaporation) ? GradTemp.ToArray() : new SinglePhaseField[D])); // linearization velocity: if (this.U0meanrequired) { VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray()); U0mean.Clear(); if (this.physParams.IncludeConvection) { ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } } // assemble the matrix & affine vector // =================================== // compute matrix if (OpMatrix != null) { //Op.ComputeMatrixEx(Tracker, // ColMapping, Params, RowMapping, // OpMatrix, OpAffine, false, time, true, // AgglomeratedCellLengthScales, // InterfaceLengths, SlipLengths, // SpcToCompute); XSpatialOperator.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute); foreach (var kv in AgglomeratedCellLengthScales) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); if (evaporation) { BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count);; // this.LsTrk.GridDat.GetBoundaryCells().GetBitMask(); mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion); } } if (Op.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } mtxBuilder.time = time; mtxBuilder.ComputeMatrix(OpMatrix, OpAffine); #if DEBUG // remark: remove this piece in a few months from now on (09may18) if no problems occur { BlockMsrMatrix checkOpMatrix = new BlockMsrMatrix(RowMapping, ColMapping); double[] checkAffine = new double[OpAffine.Length]; Op.ComputeMatrixEx(Tracker, ColMapping, Params, RowMapping, OpMatrix, OpAffine, false, time, true, AgglomeratedCellLengthScales, InterfaceLengths, SlipLengths, SpcToCompute); double[] checkResult = checkAffine.CloneAs(); var currentVec = new CoordinateVector(CurrentState.ToArray()); checkOpMatrix.SpMV(1.0, new CoordinateVector(CurrentState.ToArray()), 1.0, checkResult); double L2_dist = GenericBlas.L2DistPow2(checkResult, OpAffine).MPISum().Sqrt(); double RefNorm = (new double[] { checkResult.L2NormPow2(), OpAffine.L2NormPow2(), currentVec.L2NormPow2() }).MPISum().Max().Sqrt(); Assert.LessOrEqual(L2_dist, RefNorm * 1.0e-6); Debug.Assert(L2_dist < RefNorm * 1.0e-6); } #endif } else { XSpatialOperator.XEvaluatorNonlin eval = Op.GetEvaluatorEx(Tracker, CurrentState.ToArray(), Params, RowMapping, SpcToCompute); foreach (var kv in AgglomeratedCellLengthScales) { eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); if (evaporation) { BitArray EvapMicroRegion = new BitArray(this.LsTrk.GridDat.Cells.Count); eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("EvapMicroRegion", EvapMicroRegion); } } if (Op.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } eval.time = time; eval.Evaluate(1.0, 1.0, OpAffine); } // check // ===== /* * { * DGField[] testDomainFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray(); * CoordinateVector test = new CoordinateVector(testDomainFieldS); * * DGField[] errFieldS = ColMapping.BasisS.Select(bb => new XDGField(bb as XDGBasis)).ToArray(); * CoordinateVector Err = new CoordinateVector(errFieldS); * * var eval = Op.GetEvaluatorEx(LsTrk, * testDomainFieldS, Params, RowMapping); * * foreach (var s in this.LsTrk.SpeciesIdS) * eval.SpeciesOperatorCoefficients[s].CellLengthScales = AgglomeratedCellLengthScales[s]; * * eval.time = time; * int L = test.Count; * Random r = new Random(); * for(int i = 0; i < L; i++) { * test[i] = r.NextDouble(); * } * * * * double[] R1 = new double[L]; * double[] R2 = new double[L]; * eval.Evaluate(1.0, 1.0, R1); * * R2.AccV(1.0, OpAffine); * OpMatrix.SpMV(1.0, test, 1.0, R2); * * Err.AccV(+1.0, R1); * Err.AccV(-1.0, R2); * * double ErrDist = GenericBlas.L2DistPow2(R1, R2).MPISum().Sqrt(); * * double Ref = test.L2NormPow2().MPISum().Sqrt(); * * Debug.Assert(ErrDist <= Ref*1.0e-5, "Mismatch between explicit evaluation of XDG operator and matrix."); * } */ }
/// <summary> /// ctor for the operator factory, where the equation compnents are set /// </summary> /// <param name="config"></param> /// <param name="_LsTrk"></param> /// <param name="_HMFdegree"></param> /// <param name="BcMap"></param> /// <param name="degU"></param> public XRheology_OperatorFactory(XRheology_OperatorConfiguration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int _stressDegree, int degU) { this.LsTrk = _LsTrk; this.D = _LsTrk.GridDat.SpatialDimension; this.HMFDegree = _HMFdegree; this.physParams = config.getPhysParams; this.dntParams = config.getDntParams; this.useJacobianForOperatorMatrix = config.isUseJacobian; this.useArtificialDiffusion = config.isUseArtificialDiffusion; // test input // ========== { if (config.getDomBlocks.GetLength(0) != 3 || config.getCodBlocks.GetLength(0) != 3) { throw new ArgumentException(); } //if ((config.getPhysParams.Weissenberg_a <= 0) && (config.getPhysParams.Weissenberg_a <= 0)) { // config.isOldroydB = false; //} else { // if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0)) // throw new ArgumentException(); //} //if ((config.getPhysParams.reynolds_A <= 0) && (config.getPhysParams.reynolds_B <= 0)) { // config.isViscous = false; //} else { // if ((config.getPhysParams.reynolds_A <= 0) || (config.getPhysParams.reynolds_B <= 0)) // throw new ArgumentException(); //if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.rho_B <= 0)) // throw new ArgumentException(); if (_LsTrk.SpeciesNames.Count != 2) { throw new ArgumentException(); } if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B"))) { throw new ArgumentException(); } } // full operator: // ============== CodName = ArrayTools.Cat(EquationNames.MomentumEquations(this.D), EquationNames.ContinuityEquation, EquationNames.Constitutive(this.D)); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(this.D), VariableNames.Velocity0MeanVector(this.D), VariableNames.VelocityX_GradientVector(), VariableNames.VelocityY_GradientVector(), VariableNames.StressXXP, VariableNames.StressXYP, VariableNames.StressYYP, // "artificialViscosity", VariableNames.NormalVector(this.D), VariableNames.Curvature, VariableNames.SurfaceForceVector(this.D) ); DomName = ArrayTools.Cat(VariableNames.VelocityVector(this.D), VariableNames.Pressure, VariableNames.StressXX, VariableNames.StressXY, VariableNames.StressYY); // selected part: if (config.getCodBlocks[0]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, this.D)); } if (config.getCodBlocks[1]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(this.D, 1)); } if (config.getCodBlocks[2]) { CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(this.D + 1, 3)); } if (config.getDomBlocks[0]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, this.D)); } if (config.getDomBlocks[1]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D, 1)); } if (config.getDomBlocks[2]) { DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D + 1, 3)); } // create Operator // =============== m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesIdS.ToArray()); // add components // ============================ // species bulk components for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++) { // Navier Stokes equations XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); // continuity equation if (config.isContinuity) { XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap); } // constitutive equation XConstitutiveOperatorComponentsFactory.AddSpeciesConstitutive(m_XOp, config, this.D, stressDegree, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired); } // interface components XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, this.D, BcMap, LsTrk); // surface stress tensor XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, this.D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force XConstitutiveOperatorComponentsFactory.AddInterfaceConstitutive(m_XOp, config, this.D, BcMap, LsTrk); //viscosity of stresses at constitutive if (config.isContinuity) { XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, this.D, LsTrk); // continuity equation } m_XOp.Commit(); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="OpMatrix"></param> /// <param name="OpAffine"></param> /// <param name="RowMapping"></param> /// <param name="ColMapping"></param> /// <param name="CurrentState"></param> /// <param name="AgglomeratedCellLengthScales"></param> /// <param name="time"></param> /// <param name="CutCellQuadOrder"></param> /// <param name="SurfaceForce"></param> /// <param name="LevelSetGradient"></param> /// <param name="ExternalyProvidedCurvature"></param> public void AssembleMatrix <T>(BlockMsrMatrix OpMatrix, double[] OpAffine, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping, IEnumerable <T> CurrentState, Dictionary <SpeciesId, MultidimensionalArray> AgglomeratedCellLengthScales, double time, int CutCellQuadOrder, VectorField <SinglePhaseField> SurfaceForce, VectorField <SinglePhaseField> LevelSetGradient, SinglePhaseField ExternalyProvidedCurvature) where T : DGField { // checks: if (ColMapping.BasisS.Count != this.m_XOp.DomainVar.Count) { throw new ArgumentException(); } if (RowMapping.BasisS.Count != this.m_XOp.CodomainVar.Count) { throw new ArgumentException(); } int D = this.LsTrk.GridDat.SpatialDimension; if (CurrentState != null && CurrentState.Count() != (D + 1)) { throw new ArgumentException(); } if (OpMatrix == null && CurrentState == null) { throw new ArgumentException(); } DGField[] U0; if (CurrentState != null) { U0 = CurrentState.Take(D).ToArray(); } else { U0 = null; } // advanced settings for the navier slip boundary condition // ======================================================== CellMask SlipArea; switch (this.dntParams.GNBC_Localization) { case NavierSlip_Localization.Bulk: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask; break; } case NavierSlip_Localization.ContactLine: { SlipArea = null; break; } case NavierSlip_Localization.Nearband: { SlipArea = this.LsTrk.GridDat.BoundaryCells.VolumeMask.Intersect(this.LsTrk.Regions.GetNearFieldMask(this.LsTrk.NearRegionWidth)); break; } case NavierSlip_Localization.Prescribed: { throw new NotImplementedException(); } default: throw new ArgumentException(); } MultidimensionalArray SlipLengths; SlipLengths = this.LsTrk.GridDat.Cells.h_min.CloneAs(); SlipLengths.Clear(); //SlipLengths.AccConstant(-1.0); if (SlipArea != null) { foreach (Chunk cnk in SlipArea) { for (int i = cnk.i0; i < cnk.JE; i++) { switch (this.dntParams.GNBC_SlipLength) { case NavierSlip_SlipLength.hmin_DG: { int degU = ColMapping.BasisS.ToArray()[0].Degree; SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i] / (degU + 1); break; } case NavierSlip_SlipLength.hmin_Grid: { SlipLengths[i] = SlipLengths[i] = this.LsTrk.GridDat.Cells.h_min[i]; break; } case NavierSlip_SlipLength.Prescribed_SlipLength: { SlipLengths[i] = this.physParams.sliplength; break; } case NavierSlip_SlipLength.Prescribed_Beta: { SlipLengths[i] = -1.0; break; } } } } } // parameter assembly // ================== LevelSet Phi = (LevelSet)(this.LsTrk.LevelSets[0]); SpeciesId[] SpcToCompute = AgglomeratedCellLengthScales.Keys.ToArray(); // normals: SinglePhaseField[] Normals; // Normal vectors: length not normalized - will be normalized at each quad node within the flux functions. if (this.NormalsRequired) { if (LevelSetGradient == null) { LevelSetGradient = new VectorField <SinglePhaseField>(D, Phi.Basis, SinglePhaseField.Factory); LevelSetGradient.Gradient(1.0, Phi); } Normals = LevelSetGradient.ToArray(); } else { Normals = new SinglePhaseField[D]; } // curvature: SinglePhaseField Curvature; if (this.CurvatureRequired) { Curvature = ExternalyProvidedCurvature; } else { Curvature = null; } // linearization velocity: DGField[] U0_U0mean; if (this.U0meanrequired) { XDGBasis U0meanBasis = new XDGBasis(this.LsTrk, 0); VectorField <XDGField> U0mean = new VectorField <XDGField>(D, U0meanBasis, "U0mean_", XDGField.Factory); U0_U0mean = ArrayTools.Cat <DGField>(U0, U0mean); } else { U0_U0mean = new DGField[2 * D]; } // Temperature gradient for evaporation //VectorField<DGField> GradTemp = new VectorField<DGField>(D, new XDGBasis(LsTrk, 0), XDGField.Factory); //if (CoupledCurrentState != null) { // DGField Temp = CoupledCurrentState.ToArray()[0]; // GradTemp = new VectorField<DGField>(D, Temp.Basis, "GradTemp", XDGField.Factory); // XNSEUtils.ComputeGradientForParam(Temp, GradTemp, this.LsTrk); //} // concatenate everything var Params = ArrayTools.Cat <DGField>( U0_U0mean, Normals, Curvature, ((SurfaceForce != null) ? SurfaceForce.ToArray() : new SinglePhaseField[D])); // linearization velocity: if (this.U0meanrequired) { VectorField <XDGField> U0mean = new VectorField <XDGField>(U0_U0mean.Skip(D).Take(D).Select(f => ((XDGField)f)).ToArray()); U0mean.Clear(); if (this.physParams.IncludeConvection) { ComputeAverageU(U0, U0mean, CutCellQuadOrder, LsTrk.GetXDGSpaceMetrics(SpcToCompute, CutCellQuadOrder, 1).XQuadSchemeHelper); } } // assemble the matrix & affine vector // =================================== IDictionary <SpeciesId, MultidimensionalArray> InterfaceLengths = this.LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), CutCellQuadOrder).CutCellMetrics.InterfaceArea; // compute matrix if (OpMatrix != null) { XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = this.m_XOp.GetMatrixBuilder(LsTrk, ColMapping, Params, RowMapping, SpcToCompute); foreach (var kv in AgglomeratedCellLengthScales) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { mtxBuilder.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } mtxBuilder.time = time; mtxBuilder.ComputeMatrix(OpMatrix, OpAffine); } else { XSpatialOperatorMk2.XEvaluatorNonlin eval = this.m_XOp.GetEvaluatorEx(this.LsTrk, CurrentState.ToArray(), Params, RowMapping, SpcToCompute); foreach (var kv in AgglomeratedCellLengthScales) { eval.SpeciesOperatorCoefficients[kv.Key].CellLengthScales = kv.Value; eval.SpeciesOperatorCoefficients[kv.Key].EdgeLengthScales = kv.Value; eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("SlipLengths", SlipLengths); } if (this.m_XOp.SurfaceElementOperator.TotalNoOfComponents > 0) { foreach (var kv in InterfaceLengths) { eval.SpeciesOperatorCoefficients[kv.Key].UserDefinedValues.Add("InterfaceLengths", kv.Value); } } eval.time = time; eval.Evaluate(1.0, 1.0, OpAffine); } }
/// <summary> /// Control for the testcase according to Smolianksi /// </summary> /// <param name="p"></param> /// <param name="kelem"></param> /// <param name="_DbPath"></param> /// <returns></returns> public static XNSE_Control RT_Smolianski(int p = 2, int kelem = 32, string _DbPath = null) { XNSE_Control C = new XNSE_Control(); // basic database options // ====================== #region db //_DbPath = @"D:\local\local_Testcase_databases\Testcase_RTinstability"; _DbPath = @"\\fdyprime\userspace\smuda\cluster\cluster_db"; C.DbPath = _DbPath; C.savetodb = C.DbPath != null; C.ProjectName = "XNSE/RT-Instability"; C.Tags.Add("unstable"); //C.Tags.Add("smolianski"); #endregion //C.LogValues = XNSE_Control.LoggingValues.Wavelike; //C.WriteInterfaceP = true; // DG degrees // ========== #region degrees C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = p - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 4, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Curvature", new FieldOpts() { Degree = 8, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); #endregion // grid genration // ============== #region grid double L = 1; double H = 4.0 * L; C.GridFunc = delegate() { // Smolianski //double[] Xnodes = GenericBlas.Linspace(0, L, kelem + 1); //double[] Ynodes = GenericBlas.Linspace(0, H, (4 * kelem) + 1); //var grd = Grid2D.Cartesian2DGrid(Xnodes, Ynodes, periodicX: false); double[] xNodes = GenericBlas.Linspace(0, L, kelem + 1); double[] _yNodes1 = GenericBlas.Linspace(0, 2.2, (int)(2.2 * kelem) + 1); _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = Grid1D.TanhSpacing(2.2, 4.0, (kelem / 2) + 1, 1.5, true); var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: false); grd.EdgeTagNames.Add(1, "wall_lower"); grd.EdgeTagNames.Add(2, "wall_upper"); grd.EdgeTagNames.Add(3, "freeslip_left"); grd.EdgeTagNames.Add(4, "freeslip_right"); grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1]) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - H) <= 1.0e-8) { et = 2; } if (Math.Abs(X[0]) <= 1.0e-8) { et = 3; } if (Math.Abs(X[0] - L) <= 1.0e-8) { et = 4; } return(et); }); return(grd); }; //double L = 1; //lambda_instable; //double H = 1.0 * L; //double H_interf = L / 4.0; ////int xkelem = 20; //int ykelem_Interface = 1 * kelem / 2; //int ykelem_outer = kelem / 2; //C.GridFunc = delegate () { // double[] xNodes = GenericBlas.Linspace(0, L, kelem + 1); // //double[] Ynodes_Interface = GenericBlas.Linspace(-(H_interf) / 2.0, (H_interf) / 2.0, ykelem_Interface); // //Ynodes_Interface = Ynodes_Interface.GetSubVector(1, Ynodes_Interface.GetLength(0) - 2); // //double[] Ynodes_lower = GenericBlas.Linspace(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1); // //double[] Ynodes_upper = GenericBlas.Linspace((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1); // //double[] Ynodes = Ynodes_lower.Concat(Ynodes_Interface).ToArray().Concat(Ynodes_upper).ToArray(); // var _yNodes1 = Grid1D.TanhSpacing(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1, 1.5, false); // _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); // var _yNodes2 = GenericBlas.Linspace(-H_interf / 2.0, H_interf / 2.0, ykelem_Interface); // _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); // var _yNodes3 = Grid1D.TanhSpacing((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1, 1.5, true); // var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); // var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: true); // grd.EdgeTagNames.Add(1, "wall_lower"); // grd.EdgeTagNames.Add(2, "wall_upper"); // grd.DefineEdgeTags(delegate (double[] X) { // byte et = 0; // if (Math.Abs(X[1] + ((H_interf / 2.0) + H)) <= 1.0e-8) // et = 1; // if (Math.Abs(X[1] - ((H_interf / 2.0) + H)) <= 1.0e-8) // et = 2; // if (Math.Abs(X[0]) <= 1.0e-8) // et = 3; // if (Math.Abs(X[0] - L) <= 1.0e-8) // et = 4; // return et; // }); // return grd; //}; #endregion // boundary conditions // =================== #region BC C.AddBoundaryValue("wall_lower"); C.AddBoundaryValue("wall_upper"); C.AddBoundaryValue("freeslip_left"); C.AddBoundaryValue("freeslip_right"); #endregion // Initial Values // ============== #region init //int k = 1; double A0 = 0.05; C.InitialValues_Evaluators.Add("Phi", (X => X[1] - (2.0 + A0 * Math.Cos(2.0 * Math.PI * X[0])))); C.InitialValues_Evaluators.Add("VelocityY#A", X => 0.0); C.InitialValues_Evaluators.Add("VelocityY#B", X => 0.0); double g = 1.0; C.InitialValues_Evaluators.Add("GravityY#A", X => - g); C.InitialValues_Evaluators.Add("GravityY#B", X => - g); //var database = new DatabaseInfo(_DbPath); //Guid restartID = new Guid("12b8c9f7-504c-40c4-a548-304a2e2aa14f"); //C.RestartInfo = new Tuple<Guid, Foundation.IO.TimestepNumber>(restartID, 3420); #endregion // Physical Parameters // =================== #region physics //C.PhysicalParameters.rho_A = 0.17; //C.PhysicalParameters.rho_B = 1.2; //C.PhysicalParameters.mu_A = 0.17e-2; //C.PhysicalParameters.mu_B = 1.2e-2; //C.PhysicalParameters.Sigma = 0.0; C.PhysicalParameters.rho_A = 0.17; C.PhysicalParameters.rho_B = 1.2; C.PhysicalParameters.mu_A = 0.003; C.PhysicalParameters.mu_B = 0.003; C.PhysicalParameters.Sigma = 0.0; // corresponding dt = 1e-3; //C.PhysicalParameters.Sigma = 0.015; // corresponding dt = 4e-3; C.PhysicalParameters.IncludeConvection = true; C.PhysicalParameters.Material = true; #endregion // additional parameters // ===================== //double[] param = new double[4]; //param[0] = k; // wavenumber //param[1] = L; // wavelength //param[2] = A0; // initial disturbance //param[3] = g; // y-gravity //C.AdditionalParameters = param; // misc. solver options // ==================== #region solver //C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2; //C.AdvancedDiscretizationOptions.PenaltySafety = 40; //C.AdvancedDiscretizationOptions.UseGhostPenalties = true; C.LSContiProjectionMethod = ContinuityProjectionOption.SpecFEM; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib; C.Solver_MaxIterations = 50; C.Solver_ConvergenceCriterion = 1e-8; C.LevelSet_ConvergenceCriterion = 1e-6; C.LinearSolver = DirectSolver._whichSolver.MUMPS; C.AdvancedDiscretizationOptions.FilterConfiguration = CurvatureAlgorithms.FilterConfiguration.Default; C.AdvancedDiscretizationOptions.SST_isotropicMode = Solution.XNSECommon.SurfaceStressTensor_IsotropicMode.Curvature_Projected; C.AdvancedDiscretizationOptions.FilterConfiguration.FilterCurvatureCycles = 1; #endregion // Timestepping // ============ #region time C.CompMode = AppControl._CompMode.Transient; C.Timestepper_Scheme = XNSE_Control.TimesteppingScheme.ImplicitEuler; C.Timestepper_BDFinit = TimeStepperInit.SingleInit; //C.dt_increment = 20; C.Timestepper_LevelSetHandling = LevelSetHandling.LieSplitting; double dt = 1e-3; C.dtMax = dt; C.dtMin = dt; C.Endtime = 1000; C.NoOfTimesteps = 4000; C.saveperiod = 4; #endregion return(C); }
/// <summary> /// One Iteration of the ReInitialization /// Operators must be built first /// </summary> /// <param name="ChangeRate"> /// L2-Norm of the Change-Rate in the level set in this reinit step /// </param> /// <param name="Restriction"> /// The subgrid, on which the ReInit is performed /// </param> /// <param name="IncludingInterface"> /// !! Not yet functional !! /// True, if the subgrid contains the interface, this causes all external edges of the subgrid to be treated as boundaries /// False, for the rest of the domain, thus the flux to the adjacent cells wil be evaluated /// </param> /// <returns></returns> public void ReInitSingleStep(out double ChangeRate, SubGrid Restriction = null, bool IncludingInterface = true) { if (!IncludingInterface) { throw new NotImplementedException("Untested, not yet functional!"); } using (new FuncTrace()) { /// Init Residuals Residual.Clear(); Residual.Acc(1.0, Phi); OldPhi.Clear(); OldPhi.Acc(1.0, Phi); NewPhi.Clear(); NewPhi.Acc(1.0, Phi); CellMask RestrictionMask = Restriction == null ? null : Restriction.VolumeMask; //if (Control.Upwinding && UpdateDirection && IterationCounter % 10 == 0) { if (false && Control.Upwinding && UpdateDirection) { //if (Control.Upwinding && UpdateDirection) { UpdateBulkMatrix(Restriction); } UpdateDirection = false; // RHS part RHSField.CoordinateVector.Clear(); //Operator_RHS.Evaluate(NewPhi.Mapping, RHSField.Mapping); Operator_RHS.Evaluate(double.NaN, IncludingInterface ? Restriction : null, IncludingInterface ? SubGridBoundaryModes.BoundaryEdge : SubGridBoundaryModes.InnerEdge, ArrayTools.Cat(new DGField[] { Phi }, parameterFields, new DGField[] { RHSField })); #if DEBUG RHSField.CheckForNanOrInf(); #endif // solve // ===== double[] RHS = OpAffine.CloneAs(); RHS.ScaleV(-1.0); RHS.AccV(1.0, RHSField.CoordinateVector); SolverResult Result; if (Restriction != null) { SubRHS.Clear(); SubSolution.Clear(); SubRHS.AccV(1.0, RHS, default(int[]), SubVecIdx); SubSolution.AccV(1.0, NewPhi.CoordinateVector, default(int[]), SubVecIdx); Result = slv.Solve(SubSolution, SubRHS); NewPhi.Clear(RestrictionMask); NewPhi.CoordinateVector.AccV(1.0, SubSolution, SubVecIdx, default(int[])); } else { Result = slv.Solve(NewPhi.CoordinateVector, RHS); } #if Debug OpMatrix.SpMV(-1.0, NewPhi.CoordinateVector, 1.0, RHS); Console.WriteLine("LinearSolver: {0} Iterations, Converged={1}, Residual = {2} ", Result.NoOfIterations, Result.Converged, RHS.L2Norm()); #endif // Apply underrelaxation Phi.Clear(RestrictionMask); Phi.Acc(1 - underrelaxation, OldPhi, RestrictionMask); Phi.Acc(underrelaxation, NewPhi, RestrictionMask); Residual.Acc(-1.0, Phi, RestrictionMask); ChangeRate = Residual.L2Norm(RestrictionMask); //Calculate LevelSetGradient.Clear(); LevelSetGradient.Gradient(1.0, Phi, RestrictionMask); //LevelSetGradient.GradientByFlux(1.0, Phi); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient, RestrictionMask); if (Control.Upwinding) { //RestrictionMask.GetBitMask(); for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++) { NewDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]); //NewDirection[i] = MeanLevelSetGradient.CoordinateVector[i]; OldDirection[i] -= NewDirection[i]; } double MaxDiff = OldDirection.L2Norm(); //if (MaxDiff > 1E-20 && IterationCounter % 10 == 0 ) { //if (MaxDiff > 1E-20) { // Console.WriteLine("Direction Values differ by {0}", MaxDiff); if (MaxDiff > 0.2) { //UpdateDirection = true; //Console.WriteLine("Direction Values differ by {0} => Updating ReInit-Matrix", MaxDiff); } ; //} //Console.WriteLine("HACK!!! Updating Upwind Matrix everytime!"); //UpdateDirection = true; // Reset Value OldDirection.Clear(); OldDirection.AccV(1.0, NewDirection); } } }
/// <summary> /// Control for various testing /// </summary> /// <param name="p"></param> /// <param name="xkelem"></param> /// <param name="dt"></param> /// <param name="t_end"></param> /// <param name="_DbPath"></param> /// <returns></returns> public static XNSE_Control RT(int p = 2, int xkelem = 16, string _DbPath = null) { XNSE_Control C = new XNSE_Control(); // basic database options // ====================== #region db _DbPath = @"D:\local\local_Testcase_databases\Testcase_RTinstability"; //_DbPath = @"\\fdyprime\userspace\smuda\cluster\cluster_db"; C.DbPath = _DbPath; C.savetodb = C.DbPath != null; C.ProjectName = "XNSE/RT-Instability"; C.LogValues = XNSE_Control.LoggingValues.Wavelike; C.WriteInterfaceP = true; #endregion // DG degrees // ========== #region degrees C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = p - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("GravityY", new FieldOpts() { SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Curvature", new FieldOpts() { Degree = p, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); #endregion // Physical Parameters // =================== #region physics // Capillary wave: Laplace number La = 3e5: //C.Tags.Add("La=3e5"); //double rho_l = 1e-3; //double rho_h = 1e-3; //double mu_l = 1e-5; //double mu_h = 1e-5; //double sigma = 3e-2; // Capillary wave: Laplace number La = 3000: //C.Tags.Add("La3000"); //double rho_l = 1e-3; //double rho_h = 1e-3; //double mu_l = 1e-4; //double mu_h = 1e-4; //double sigma = 3e-2; // Capillary wave: Laplace number La = 120: //double rho_l = 1e-3; //double rho_h = 1e-3; //double mu_l = 5e-4; //double mu_h = 5e-4; //double sigma = 3e-2; //double rho_l = 1e-3; //double rho_h = 1e-3; //double mu_l = 1e-6; //double mu_h = 1e-4; //double sigma = 3e-2; //double rho_l = 1; //double rho_h = 1; //double mu_l = 1e-3; //double mu_h = 1e-3; //double sigma = 1; // Air(light)-Water(heavy) //double rho_h = 1e-3; // kg / cm^3 //double rho_l = 1.2e-6; // kg / cm^3 //double mu_h = 1e-5; // kg / cm * s //double mu_l = 17.1e-8; // kg / cm * s //double sigma = 72.75e-3; // kg / s^2 // lambda_crit = 1.7121 ; lambda < lambda_c: stable // same kinematic viscosities //double rho_l = 1e-5; // kg / cm^3 //double mu_l = 1e-8; // kg / cm * s //double rho_h = 1e-3; // kg / cm^3 //double mu_h = 1e-6; // kg / cm * s // Atwood number = 0.98 //double rho_l = 7e-4; // kg / cm^3 //double mu_l = 7e-5; // kg / cm * s //double rho_h = 1e-3; // kg / cm^3 //double mu_h = 1e-4; // kg / cm * s // Atwood number = 0.1765 //double sigma = 72.75e-3; // kg / s^2 //double rho_l = 1e-3; //double mu_l = 1e-4; //double rho_h = 1; //double mu_h = 1e-1; //double sigma = 100; // kg / s^2 double rho_l = 1e-1; double mu_l = 1e-2; double rho_h = 10; double mu_h = 1; double sigma = 50; // kg / s^2 // Water-Oil //double rho_ = 8.63e-4; //double rho_B = 1.2e-6; //double mu_A = 2e-4; //double mu_B = 17.1e-8; // stable configuration //C.PhysicalParameters.rho_A = rho_h; //C.PhysicalParameters.rho_B = rho_l; //C.PhysicalParameters.mu_A = mu_h; //C.PhysicalParameters.mu_B = mu_l; //C.PhysicalParameters.Sigma = sigma; // unstable configuration C.PhysicalParameters.rho_A = rho_l; C.PhysicalParameters.rho_B = rho_h; C.PhysicalParameters.mu_A = mu_l; C.PhysicalParameters.mu_B = mu_h; C.PhysicalParameters.Sigma = sigma; //C.PhysicalParameters.Sigma = 0.0; // free surface boundary condition C.PhysicalParameters.IncludeConvection = true; C.PhysicalParameters.Material = true; #endregion // Initial displacement // =================== int kmode = 1; double H0 = 0.01; //double lambda_stable = 1; //double lambda_instable = 4; //Func<double, double> displacement = x => ((lambda_stable / 100) * Math.Sin(x * 2 * Math.PI / lambda_stable )) + ((lambda_instable / 100) * Math.Sin(x * 2 * Math.PI / lambda_instable)); Func <double, double> displacement = x => (H0 * Math.Sin(x * 2 * Math.PI * (double)kmode)); // grid genration // ============== #region grid double L = 1; //lambda_instable; double H = 1.0 * L; double H_interf = L / 4.0; //int xkelem = 20; int ykelem_Interface = 1 * xkelem; // /2 int ykelem_outer = xkelem / 2; // /2 C.GridFunc = delegate() { double[] xNodes = GenericBlas.Linspace(0, L, xkelem + 1); //double[] Ynodes_Interface = GenericBlas.Linspace(-(H_interf) / 2.0, (H_interf) / 2.0, ykelem_Interface); //Ynodes_Interface = Ynodes_Interface.GetSubVector(1, Ynodes_Interface.GetLength(0) - 2); //double[] Ynodes_lower = GenericBlas.Linspace(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1); //double[] Ynodes_upper = GenericBlas.Linspace((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1); //double[] Ynodes = Ynodes_lower.Concat(Ynodes_Interface).ToArray().Concat(Ynodes_upper).ToArray(); var _yNodes1 = Grid1D.TanhSpacing(-(H + (H_interf / 2.0)), -(H_interf / 2.0), ykelem_outer + 1, 1.5, false); _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = GenericBlas.Linspace(-H_interf / 2.0, H_interf / 2.0, ykelem_Interface); _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); var _yNodes3 = Grid1D.TanhSpacing((H_interf / 2.0), H + (H_interf / 2.0), ykelem_outer + 1, 1.5, true); var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: true); grd.EdgeTagNames.Add(1, "wall_lower"); grd.EdgeTagNames.Add(2, "wall_upper"); grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] + ((H_interf / 2.0) + H)) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - ((H_interf / 2.0) + H)) <= 1.0e-8) { et = 2; } if (Math.Abs(X[0]) <= 1.0e-8) { et = 3; } if (Math.Abs(X[0] - L) <= 1.0e-8) { et = 4; } return(et); }); return(grd); }; // nach Popinet //C.GridFunc = delegate () { // double[] Xnodes = GenericBlas.Linspace(0, L, xkelem + 1); // double[] Ynodes = GenericBlas.Linspace(-3.0 * L / 2.0, 3.0 * L / 2.0, (3 * xkelem) + 1); // var grd = Grid2D.Cartesian2DGrid(Xnodes, Ynodes, periodicX: true); // grd.EdgeTagNames.Add(1, "wall_lower"); // grd.EdgeTagNames.Add(2, "wall_upper"); // grd.DefineEdgeTags(delegate (double[] X) { // byte et = 0; // if (Math.Abs(X[1] + (3.0 * L / 2.0)) <= 1.0e-8) // et = 1; // if (Math.Abs(X[1] - (3.0 * L / 2.0)) <= 1.0e-8) // et = 2; // if (Math.Abs(X[0]) <= 1.0e-8) // et = 3; // if (Math.Abs(X[0] - L) <= 1.0e-8) // et = 4; // return et; // }); // return grd; //}; #endregion // boundary conditions // =================== #region BC C.AddBoundaryValue("wall_lower"); C.AddBoundaryValue("wall_upper"); #endregion // Initial Values // ============== #region init Func <double, double> PeriodicFunc = x => displacement(x); //superposed higher frequent disturbance //double lambda_dist = lambda / (double)(xkelem / 2); //if (lambda_dist > 0.0) { // double A0_dist = A0 / 5.0; // Func<double, double> disturbance = x => A0_dist * Math.Sin(x * 2 * Math.PI / lambda_dist); // PeriodicFunc = x => (displacement(x) + disturbance(x)); //} C.InitialValues_Evaluators.Add("Phi", (X => X[1] - (PeriodicFunc(X[0])))); C.InitialValues_Evaluators.Add("VelocityX#A", X => 0.0); C.InitialValues_Evaluators.Add("VelocityX#B", X => 0.0); double g = 9.81; // e2; C.InitialValues_Evaluators.Add("GravityY#A", X => - g); C.InitialValues_Evaluators.Add("GravityY#B", X => - g); //var database = new DatabaseInfo(_DbPath); //Guid restartID = new Guid("0141eba2-8d7b-4593-8595-bfff12dbfc40"); //C.RestartInfo = new Tuple<Guid, Foundation.IO.TimestepNumber>(restartID, null); #endregion // misc. solver options // ==================== #region solver //C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2; //C.AdvancedDiscretizationOptions.PenaltySafety = 40; //C.AdvancedDiscretizationOptions.UseGhostPenalties = true; C.LSContiProjectionMethod = ContinuityProjectionOption.SpecFEM; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib; C.NoOfMultigridLevels = 1; C.Solver_MaxIterations = 50; C.Solver_ConvergenceCriterion = 1e-8; C.LevelSet_ConvergenceCriterion = 1e-6; C.LinearSolver = DirectSolver._whichSolver.MUMPS; //C.Option_LevelSetEvolution = LevelSetEvolution.Fourier; //C.AdvancedDiscretizationOptions.surfTensionMode = SurfaceTensionMode.Curvature_Fourier; C.AdvancedDiscretizationOptions.FilterConfiguration = CurvatureAlgorithms.FilterConfiguration.Default; C.AdvancedDiscretizationOptions.SST_isotropicMode = Solution.XNSECommon.SurfaceStressTensor_IsotropicMode.Curvature_Projected; C.AdvancedDiscretizationOptions.FilterConfiguration.FilterCurvatureCycles = 1; #endregion // additional parameters // ===================== double[] param = new double[4]; param[0] = kmode; // wavenumber param[1] = L; // wavelength param[2] = H0; // initial disturbance param[3] = g; // y-gravity C.AdditionalParameters = param; // specialized Fourier Level-Set // ============================= //int numSp = 640; //C.FourierLevSetControl = new FourierLevSetControl(FourierType.Planar, numSp, L, PeriodicFunc, 1.0 / (double)xkelem) { // FourierEvolve = Fourier_Evolution.MaterialPoints, // Timestepper = FourierLevelSet_Timestepper.RungeKutta1901, // InterpolationType = Interpolationtype.CubicSplineInterpolation //}; // Timestepping // ============ #region time C.CompMode = AppControl._CompMode.Transient; C.Timestepper_Scheme = XNSE_Control.TimesteppingScheme.ImplicitEuler; C.Timestepper_BDFinit = TimeStepperInit.SingleInit; //C.dt_increment = 20; C.Timestepper_LevelSetHandling = LevelSetHandling.LieSplitting; double dt = 1e-4; C.dtMax = dt; C.dtMin = dt; C.Endtime = 1000; C.NoOfTimesteps = 4000; C.saveperiod = 4; #endregion return(C); }
public static IBM_Control[] IBMCylinderFlow(string _DbPath = null, int k = 2, bool xPeriodic = false, double VelXBase = 0.0) { List <IBM_Control> R = new List <IBM_Control>(); foreach (int i in new int[] { 3 }) { IBM_Control C = new IBM_Control(); C.Paramstudy_CaseIdentification = new Tuple <string, object>[] { new Tuple <string, object>("k", i), }; k = i; const double BaseSize = 1.0; // basic database options // ====================== C.DbPath = @"\\fdyprime\userspace\krause\BoSSS_DBs\Paper_CellAgglo01_Penalty4"; C.savetodb = false; C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2"; switch (i) { case 1: C.MeshFactor = 1.33; // was 1.33 break; case 2: C.MeshFactor = 0.92; break; case 3: C.MeshFactor = 0.7; // was 07 break; default: throw new ApplicationException(); } C.ProjectDescription = "Cylinder"; C.Tags.Add("with immersed boundary method"); // DG degrees // ========== C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); //Console.WriteLine("Achtung: equal order!!!!"); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = k - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); //grid and boundary conditions // ============================ C.GridFunc = delegate { var _xNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(10 * C.MeshFactor), 0.5, false); //10 _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1)); var _xNodes2 = GenericBlas.Linspace(-1, 2, Convert.ToInt32(35 * C.MeshFactor)); //35 _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1)); var _xNodes3 = Grid1D.TanhSpacing(2, 20, Convert.ToInt32(60 * C.MeshFactor), 1.5, true); //60 var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3); var _yNodes1 = Grid1D.TanhSpacing(-2, -1, Convert.ToInt32(7 * C.MeshFactor), 0.9, false); //7 _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = GenericBlas.Linspace(-1, 1, Convert.ToInt32(25 * C.MeshFactor)); //25 _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); var _yNodes3 = Grid1D.TanhSpacing(1, 2.1, Convert.ToInt32(7 * C.MeshFactor), 1.1, true); //7 var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25); //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic); grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); if (!xPeriodic) { grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); } grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) { et = 2; } if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8) { et = 3; } if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) { et = 4; } Debug.Assert(et != 0); return(et); }); Console.WriteLine("Cells: {0}", grd.NumberOfCells); return(grd); }; //C.GridFunc = delegate { // // Box1 // var box1_p1 = new double[2] { -2, -2 }; // var box1_p2 = new double[2] { 20, 2.1 }; // var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15 // // Box2 // var box2_p1 = new double[2] { -2, -2 }; // var box2_p2 = new double[2] { 3, 2.1 }; // var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30 // // Box3 // var box3_p1 = new double[2] { -2, -1 }; // var box3_p2 = new double[2] { 1, 1 }; // var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58 ; k2: 32,38; k3: 24, 30 // // Box4 // var box4_p1 = new double[2] { -0.7, -0.72 }; // var box4_p2 = new double[2] { 0.7, 0.7 }; // var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84 ; k2: 30,56; k3: 22, 42 // var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4); // grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); // grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); // if (!xPeriodic) { // grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); // grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); // } // grd.DefineEdgeTags(delegate (double[] X) { // byte et = 0; // if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8) // et = 1; // if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) // et = 2; // if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8) // et = 3; // if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) // et = 4; // Debug.Assert(et != 0); // return et; // }); // Console.WriteLine("Cells: {0}", grd.NumberOfCells); // return grd; //}; C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0); C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1)) if (!xPeriodic) { C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1))); //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1); } C.AddBoundaryCondition("Pressure_Outlet_right"); // Initial Values // ============== double radius = 0.5; C.PhysicalParameters.rho_A = 1; C.PhysicalParameters.mu_A = 1.0 / 20; //C.InitialValues.Add("Phi", X => phi(X, 0)); //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2())); // quadratic form // ); C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2()); //C.InitialValues.Add("Phi", X => -1); C.InitialValues_Evaluators.Add("VelocityX", X => 4 * 1.5 * (X[1] + 2) * (4.1 - (X[1] + 2)) / (4.1 * 4.1)); //C.InitialValues.Add("VelocityX", delegate (double[] X) //{ // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + y.Pow2()); // double xVel = 0; // if (R < 0.75) // { // xVel = 1; // } // return xVel; //}); //C.InitialValues.Add("VelocityY", delegate (double[] X) { // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2()); // double yVel = 0; // if (R < 0.75) { // yVel = 1; // } // return yVel; //}); // For restart //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95); //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f"); // Physical Parameters // =================== C.PhysicalParameters.IncludeConvection = true; // misc. solver options // ==================== C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2; C.LevelSetSmoothing = false; //C.option_solver = "direct"; C.MaxKrylovDim = 20; C.MaxSolverIterations = 50; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite; C.NoOfMultigridLevels = 0; // Timestepping // ============ C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.ImplicitEuler; double dt = 0.05; C.dtMax = dt; C.dtMin = dt; C.Endtime = 70; C.NoOfTimesteps = 1000000; // haben fertig... // =============== R.Add(C); } return(R.ToArray()); }
private static int[] ComputeChangeOfBasisBlock( int[] BlockLen, MultidimensionalArray In_MassMatrixBlock, MultidimensionalArray In_OperatorMatrixBlock, MultidimensionalArray OUT_LeftPC, MultidimensionalArray OUT_rightPC, Mode PCMode, out int Rank, MultidimensionalArray work) // { Rank = In_MassMatrixBlock.NoOfCols; int[] IndefRows = null; switch (PCMode) { case Mode.Eye: { OUT_LeftPC.AccEye(1.0); OUT_rightPC.AccEye(1.0); break; } case Mode.DiagBlockEquilib: { double symmErr = In_OperatorMatrixBlock.SymmetryError(); double infNorm = In_OperatorMatrixBlock.InfNorm(); if (symmErr / infNorm > 1.0e-8) { throw new ArithmeticException(string.Format("LDL_DiagBlock is not supported on unsymmetric matrices (Symm-Err: {0:0.####E-00}, Inf-Norm: {1:0.####E-00}, Quotient {2:0.####E-00}).", symmErr, infNorm, symmErr / infNorm)); } SymmInv(In_OperatorMatrixBlock, OUT_LeftPC, OUT_rightPC); //In_OperatorMatrixBlock.SymmetricLDLInversion(OUT_rightPC, null); //OUT_rightPC.TransposeTo(OUT_LeftPC); break; } case Mode.SymPart_DiagBlockEquilib: { var SymmPart = work; In_OperatorMatrixBlock.TransposeTo(SymmPart); SymmPart.Acc(1.0, In_OperatorMatrixBlock); SymmPart.Scale(0.5); SymmInv(SymmPart, OUT_LeftPC, OUT_rightPC); break; } case Mode.IdMass: { In_MassMatrixBlock.SymmetricLDLInversion(OUT_rightPC, default(double[])); OUT_rightPC.TransposeTo(OUT_LeftPC); break; } case Mode.LeftInverse_DiagBlock: { In_OperatorMatrixBlock.InvertTo(OUT_LeftPC); OUT_rightPC.AccEye(1.0); break; } case Mode.LeftInverse_Mass: { In_MassMatrixBlock.InvertTo(OUT_LeftPC); OUT_rightPC.AccEye(1.0); break; } case Mode.IdMass_DropIndefinite: { int[] ZerosEntries = ModifiedInverseChol(In_MassMatrixBlock, OUT_rightPC, 1.0e-12, false); int NoOfZeros = ZerosEntries == null ? 0 : ZerosEntries.Length; IndefRows = ZerosEntries; Rank = OUT_LeftPC.NoOfCols - NoOfZeros; OUT_rightPC.TransposeTo(OUT_LeftPC); break; } case Mode.SymPart_DiagBlockEquilib_DropIndefinite: { (Rank, IndefRows) = SymPart_DiagBlockEquilib_DropIndefinite(In_MassMatrixBlock, In_OperatorMatrixBlock, OUT_LeftPC, OUT_rightPC, work); break; } case Mode.SchurComplement: { //throw new NotImplementedException("todo"); int NoVars = BlockLen.Length; if (NoVars <= 1) { throw new NotSupportedException("The Schur complement requires at least 2 variables, moron!"); } int N1 = BlockLen.Take(NoVars - 1).Sum(); int N2 = BlockLen.Last(); int N = N1 + N2; //string TestPath = @"C:\Users\flori\OneDrive\MATLAB\Schur"; //In_OperatorMatrixBlock.SaveToTextFile(Path.Combine(TestPath, "Opm.txt")); Debug.Assert(N == In_OperatorMatrixBlock.NoOfRows); Debug.Assert(N == In_OperatorMatrixBlock.NoOfCols); (MultidimensionalArray M11, MultidimensionalArray M12, MultidimensionalArray M21, MultidimensionalArray M22) GetSubblox(MultidimensionalArray Mtx) { return( Mtx.ExtractSubArrayShallow(new[] { 0, 0 }, new[] { N1 - 1, N1 - 1 }), Mtx.ExtractSubArrayShallow(new[] { 0, N1 }, new[] { N1 - 1, N - 1 }), Mtx.ExtractSubArrayShallow(new[] { N1, 0 }, new[] { N - 1, N1 - 1 }), Mtx.ExtractSubArrayShallow(new[] { N1, N1 }, new[] { N - 1, N - 1 }) ); } var OpMtxSub = GetSubblox(In_OperatorMatrixBlock); var MamaSub = GetSubblox(In_MassMatrixBlock); var workSub = GetSubblox(work); var lpcSub = GetSubblox(OUT_LeftPC); var rpcSub = GetSubblox(OUT_rightPC); (int Rank11, int[] IndefRows11) = SymPart_DiagBlockEquilib_DropIndefinite(MamaSub.M11, OpMtxSub.M11, lpcSub.M11, rpcSub.M11, workSub.M11); // compute lpcSub.M11*OpMtxSub.M11*rpcSub.M11 // (without additional mem-alloc, yeah!) var Diag11 = workSub.M11; Diag11.GEMM(1.0, lpcSub.M11, OpMtxSub.M11, 0.0); OpMtxSub.M11.GEMM(1.0, Diag11, rpcSub.M11, 0.0); // invert diag if (Rank11 == N1) { OpMtxSub.M11.InvertTo(workSub.M11); } else { RankDefInvert(OpMtxSub.M11, workSub.M11); } // OpMtxSub.M11.GEMM(1.0, rpcSub.M11, OpMtxSub.M11, 0.0); workSub.M11.GEMM(1.0, OpMtxSub.M11, lpcSub.M11, 0.0); var Q = workSub.M11; // workSub.M21.GEMM(-1.0, OpMtxSub.M21, Q, 0.0); workSub.M12.GEMM(-1.0, Q, OpMtxSub.M12, 0.0); //rpcSub.M12.SetMatrix(workSub.M12); rpcSub.M22.AccEye(1.0); //lpcSub.M21.SetMatrix(workSub.M21); lpcSub.M22.AccEye(1.0); //OUT_LeftPC.SaveToTextFile(Path.Combine(TestPath, "Lpc.txt")); //OUT_rightPC.SaveToTextFile(Path.Combine(TestPath, "Rpc.txt")); rpcSub.M12.GEMM(1.0, Q, OpMtxSub.M12, 0.0); OpMtxSub.M22.GEMM(-1.0, OpMtxSub.M21, rpcSub.M12, 1.0); (int Rank22, int[] IndefRows22) = SymPart_DiagBlockEquilib_DropIndefinite(MamaSub.M22, OpMtxSub.M22, lpcSub.M22, rpcSub.M22, workSub.M22); lpcSub.M21.GEMM(1.0, lpcSub.M22, workSub.M21, 0.0); rpcSub.M12.GEMM(1.0, workSub.M12, rpcSub.M22, 0.0); //OUT_LeftPC.SaveToTextFile(Path.Combine(TestPath, "Lpc.txt")); //OUT_rightPC.SaveToTextFile(Path.Combine(TestPath, "Rpc.txt")); if (IndefRows11 != null && IndefRows22 != null) { IndefRows = ArrayTools.Cat(IndefRows11, IndefRows22); } else if (IndefRows11 != null) { IndefRows = IndefRows11; } else if (IndefRows22 != null) { IndefRows = IndefRows22; } else { IndefRows = null; } Rank = Rank11 + Rank22; break; } /* * case Mode.LDL_DiagBlock_DropIndefinite: { * if(In_OperatorMatrixBlock.SymmetryError() / In_OperatorMatrixBlock.InfNorm() > 1.0e-8) * throw new NotSupportedException("LDL_DiagBlock is not supported on unsymmetric matrices"); * int N = OUT_LeftPC.NoOfCols; * * MultidimensionalArray PL = MultidimensionalArray.Create(N, N); * MultidimensionalArray PR = MultidimensionalArray.Create(N, N); * * int zeros1 = CRM114(In_MassMatrixBlock, PR, 1.0e-12); * Rank = N - zeros1; * PR.TransposeTo(PL); * * var OpTr = (PL * In_OperatorMatrixBlock) * PR; * * MultidimensionalArray QL = MultidimensionalArray.Create(N, N); * MultidimensionalArray QR = MultidimensionalArray.Create(N, N); * int zeros2 = CRM114(OpTr, QR, 1.0e-12); * QR.TransposeTo(QL); * * if(zeros1 != zeros2) * // I want this to fire also in Release mode, therfore i don't use Debug.Assert(...) * throw new ApplicationException(); * * * OUT_LeftPC.GEMM(1.0, QL, PL, 0.0); * OUT_rightPC.GEMM(1.0, PR, QR, 0.0); * * //if (zeros1 > 0 || zeros2 > 0) { * // Console.WriteLine("zeros introduced: " + zeros1 + ", " + zeros2); * //} * * break; * } */ default: throw new NotImplementedException("Unknown option: " + PCMode); } return(IndefRows); }
static public IBM_Control IBMCylinderFlow(string _DbPath = null, int k = 2, bool only_channel = true, bool pardiso = true, int no_p = 1, int no_it = 1, bool load_Grid = false, string _GridGuid = null) { // int cells_x, int cells_yz IBM_Control C = new IBM_Control(); bool xPeriodic = false; int i = 2; const double BaseSize = 1.0; // basic database options // ====================== //C.DbPath = _DbPath; C.DbPath = @"\\dc1\userspace\stange\HiWi_database\PerformanceTests"; C.savetodb = true; bool restart = false; string restartSession = "67a29dcc-ade9-4704-b198-b3380e774f5a"; string restartGrid = "42e1ede0-40fc-4267-9d48-94c0397ac9a5"; bool startFromGivenGrid = true; string startGrid = "42e1ede0-40fc-4267-9d48-94c0397ac9a5"; switch (i) { case 1: C.MeshFactor = 1.258; // was 1.33 break; case 2: C.MeshFactor = 3.0; //1.77; //0.92; break; case 3: C.MeshFactor = 0.7; // was 07 break; default: throw new ApplicationException(); } if (pardiso) { if (only_channel) { C.SessionName = "2DChannel_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } else { C.SessionName = "Cylinder_Pardiso_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } } else { if (only_channel) { C.SessionName = "2DChannel_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } else { C.SessionName = "Cylinder_Mumps_k" + k + "_MeshFactor" + C.MeshFactor + "_no_p" + no_p + "_run" + no_it; } } C.saveperiod = 1; //C.SessionName = "Sphere_k" + k + "_h" + h+"Re100"; C.Tags.Add("Pardiso " + pardiso); C.Tags.Add("only channel " + only_channel); C.Tags.Add("k " + k); C.Tags.Add("no_p" + no_p); C.Tags.Add("run " + no_it); C.Tags.Add("MeshFactor " + C.MeshFactor); C.ProjectName = "FixedCylinderRe100_k" + i + "_CellAgglo02_penalty4_newMesh2"; C.ProjectDescription = "Cylinder"; // DG degrees // ========== C.FieldOptions.Add("VelocityX", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("VelocityY", new FieldOpts() { Degree = k, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); //Console.WriteLine("Achtung: equal order!!!!"); C.FieldOptions.Add("Pressure", new FieldOpts() { Degree = k - 1, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("PhiDG", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); C.FieldOptions.Add("Phi", new FieldOpts() { Degree = 2, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); // restart options // =============== if (restart) { C.RestartInfo = new Tuple <Guid, TimestepNumber>(new Guid(restartSession), -1); C.GridGuid = new Guid(restartGrid); } //grid and boundary conditions // ============================ // Initial Values // ============== double radius = 0.5; C.PhysicalParameters.rho_A = 1.0; C.PhysicalParameters.mu_A = 1.0 / 100.0; if (!restart) { if (!startFromGivenGrid) { C.GridFunc = delegate { var _xNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(10.0 * C.MeshFactor), 0.5, false); //10 _xNodes1 = _xNodes1.GetSubVector(0, (_xNodes1.Length - 1)); var _xNodes2 = GenericBlas.Linspace(-1.0, 2.0, Convert.ToInt32(35.0 * C.MeshFactor)); //35 _xNodes2 = _xNodes2.GetSubVector(0, (_xNodes2.Length - 1)); var _xNodes3 = Grid1D.TanhSpacing(2.0, 20.0, Convert.ToInt32(60.0 * C.MeshFactor), 1.5, true); //60 var xNodes = ArrayTools.Cat(_xNodes1, _xNodes2, _xNodes3); var _yNodes1 = Grid1D.TanhSpacing(-2.0, -1.0, Convert.ToInt32(7.0 * C.MeshFactor), 0.9, false); //7 _yNodes1 = _yNodes1.GetSubVector(0, (_yNodes1.Length - 1)); var _yNodes2 = GenericBlas.Linspace(-1.0, 1.0, Convert.ToInt32(25.0 * C.MeshFactor)); //25 _yNodes2 = _yNodes2.GetSubVector(0, (_yNodes2.Length - 1)); var _yNodes3 = Grid1D.TanhSpacing(1.0, 2.1, Convert.ToInt32(7.0 * C.MeshFactor), 1.1, true); //7 var yNodes = ArrayTools.Cat(_yNodes1, _yNodes2, _yNodes3); //double[] xNodes = GenericBlas.Linspace(0 * BaseSize, 22 * BaseSize, 25); //double[] yNodes = GenericBlas.Linspace(0 * BaseSize, 4.1 * BaseSize, 25); var grd = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: xPeriodic); grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); if (!xPeriodic) { grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); } grd.DefineEdgeTags(delegate(double[] X) { byte et = 0; if (Math.Abs(X[1] - (-2.0 * BaseSize)) <= 1.0e-8) { et = 1; } if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) { et = 2; } if (!xPeriodic && Math.Abs(X[0] - (-2.0 * BaseSize)) <= 1.0e-8) { et = 3; } if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) { et = 4; } Debug.Assert(et != 0); return(et); }); Console.WriteLine("Cells: {0}", grd.NumberOfCells); return(grd); }; } else { C.GridGuid = new Guid(startGrid); } if (only_channel) { C.InitialValues_Evaluators.Add("Phi", X => - 1); } else { C.InitialValues_Evaluators.Add("Phi", X => - (X[0]).Pow2() + -(X[1]).Pow2() + radius.Pow2()); } //C.InitialValues.Add("Phi", X => -1); C.InitialValues_Evaluators.Add("VelocityX", X => 4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1)); } //C.GridFunc = delegate { // // Box1 // var box1_p1 = new double[2] { -2, -2 }; // var box1_p2 = new double[2] { 20, 2.1 }; // var box1 = new GridBox(box1_p1, box1_p2, 46, 20); //k1: 70,25 ; k2: 46,20 ; k3: 35,15 // // Box2 // var box2_p1 = new double[2] { -2, -2 }; // var box2_p2 = new double[2] { 3, 2.1 }; // var box2 = new GridBox(box2_p1, box2_p2, 26, 40); //k1: 40,50 ; k2: 26,40; k3: 20, 30 // // Box3 // var box3_p1 = new double[2] { -2, -1 }; // var box3_p2 = new double[2] { 1, 1 }; // var box3 = new GridBox(box3_p1, box3_p2, 32, 38); //k1: 48,58 ; k2: 32,38; k3: 24, 30 // // Box4 // var box4_p1 = new double[2] { -0.7, -0.72 }; // var box4_p2 = new double[2] { 0.7, 0.7 }; // var box4 = new GridBox(box4_p1, box4_p2, 30, 56); //k1: 44,84 ; k2: 30,56; k3: 22, 42 // var grd = Grid2D.HangingNodes2D(box1, box2, box3,box4); // grd.EdgeTagNames.Add(1, "Velocity_Inlet_upper"); // grd.EdgeTagNames.Add(2, "Velocity_Inlet_lower"); // if (!xPeriodic) { // grd.EdgeTagNames.Add(3, "Velocity_Inlet_left"); // grd.EdgeTagNames.Add(4, "Pressure_Outlet_right"); // } // grd.DefineEdgeTags(delegate (double[] X) { // byte et = 0; // if (Math.Abs(X[1] - (-2 * BaseSize)) <= 1.0e-8) // et = 1; // if (Math.Abs(X[1] - (+2.1 * BaseSize)) <= 1.0e-8) // et = 2; // if (!xPeriodic && Math.Abs(X[0] - (-2 * BaseSize)) <= 1.0e-8) // et = 3; // if (!xPeriodic && Math.Abs(X[0] - (+20.0 * BaseSize)) <= 1.0e-8) // et = 4; // Debug.Assert(et != 0); // return et; // }); // Console.WriteLine("Cells: {0}", grd.NumberOfCells); // return grd; //}; C.AddBoundaryCondition("Velocity_Inlet_upper", "VelocityX", X => 0.0); C.AddBoundaryCondition("Velocity_Inlet_lower", "VelocityX", X => 0.0); //-(4 * 1.5 * X[1] * (4.1 - X[1]) / (4.1 * 4.1)) if (!xPeriodic) { C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX", X => (4.0 * 1.5 * (X[1] + 2.0) * (4.1 - (X[1] + 2.0)) / (4.1 * 4.1))); //C.AddBoundaryCondition("Velocity_Inlet_left", "VelocityX#A", X => 1); } C.AddBoundaryCondition("Pressure_Outlet_right"); //C.InitialValues.Add("Phi", X => phi(X, 0)); //C.InitialValues.Add("Phi", X => ((X[0] / (radius * BaseSize)) - mPx) * (X[0] / (radius * BaseSize)) - mPx) + ((X[1]) / (radius * BaseSize)) - 2.)Pow2() - radius.Pow2())); // quadratic form // ); //C.InitialValues.Add("VelocityX", delegate (double[] X) //{ // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + y.Pow2()); // double xVel = 0; // if (R < 0.75) // { // xVel = 1; // } // return xVel; //}); //C.InitialValues.Add("VelocityY", delegate (double[] X) { // double x = X[0]; // double y = X[1]; // double R = Math.Sqrt((x + 1).Pow2() + (y).Pow2()); // double yVel = 0; // if (R < 0.75) { // yVel = 1; // } // return yVel; //}); // For restart //C.RestartInfo = new Tuple<Guid, TimestepNumber>(new Guid("8f5cfed9-31c7-4be8-aa56-e92e5348e08b"), 95); //C.GridGuid = new Guid("71ffc0c4-66aa-4762-b07e-45385f34b03f"); // Physical Parameters // =================== C.PhysicalParameters.IncludeConvection = true; // misc. solver options // ==================== C.AdvancedDiscretizationOptions.CellAgglomerationThreshold = 0.2; C.AdvancedDiscretizationOptions.PenaltySafety = 4; C.LevelSetSmoothing = false; //C.option_solver = "direct"; C.MaxKrylovDim = 20; C.MaxSolverIterations = 50; C.VelocityBlockPrecondMode = MultigridOperator.Mode.SymPart_DiagBlockEquilib_DropIndefinite; //C.NoOfMultigridLevels = 0; if (pardiso) { C.whichSolver = DirectSolver._whichSolver.PARDISO; } else { C.whichSolver = DirectSolver._whichSolver.MUMPS; } // Timestepping // ============ C.Timestepper_Scheme = IBM_Control.TimesteppingScheme.BDF2; double dt = 0.1; C.dtMax = dt; C.dtMin = dt; C.Endtime = 70; C.NoOfTimesteps = 10; // haben fertig... // =============== return(C); }
/// <summary> /// Solution of the extension problem on a single cell in the far-region /// </summary> /// <param name="Phi">Input;</param> /// <param name="GradPhi">Input;</param> /// <param name="ExtProperty"></param> /// <param name="ExtPropertyMin">Input/Output: lower threshold.</param> /// <param name="ExtPropertyMax">Input/Output: upper threshold.</param> /// <param name="jCell"></param> /// <param name="Accepted"></param> /// <param name="signMod"></param> public void ExtVelSolve_Far(SinglePhaseField Phi, VectorField <SinglePhaseField> GradPhi, ConventionalDGField ExtProperty, ref double ExtPropertyMin, ref double ExtPropertyMax, int jCell, CellMask Accepted, double signMod) { GridData gDat = (GridData)(Phi.GridDat); Debug.Assert(signMod.Abs() == 1.0); Debug.Assert(ExtPropertyMin <= ExtPropertyMax); // define cell- and edge-mask for re-compute // ========================================= CellMask cM = new CellMask(gDat, Chunk.GetSingleElementChunk(jCell)); int[] Edges = gDat.iLogicalCells.Cells2Edges[jCell].CloneAs(); for (int i = 0; i < Edges.Length; i++) { Edges[i] = Math.Abs(Edges[i]) - 1; } EdgeMask eM = new EdgeMask(gDat, FromIndEnum(Edges, gDat.iLogicalEdges.Count)); // won't scale. // solve the linear extension problem for 'jCell', eventually increase // diffusion until we are satisfied with the solution // =================================================================== bool MaximumPrincipleFulfilled = false; double DiffusionCoeff = 0; // initially: try without diffusion double mini = double.NaN, maxi = double.NaN; int count = 0; while (MaximumPrincipleFulfilled == false) // as long as we are satisfied with the solution { count++; // compute operator in 'jCell' // --------------------------- int N = ExtProperty.Basis.GetLength(jCell); int i0G = ExtProperty.Mapping.GlobalUniqueCoordinateIndex(0, jCell, 0); int i0L = ExtProperty.Mapping.GlobalUniqueCoordinateIndex(0, jCell, 0); for (int n = 0; n < N; n++) { this.m_ExtvelMatrix.ClearRow(i0G + n); this.m_ExtvelAffine[i0L + n] = 0; } double penaltyBase = ((double)(ExtProperty.Basis.Degree + 1)).Pow2(); var Flux = new ExtensionVelocityForm(Accepted.GetBitMask(), signMod, penaltyBase, gDat.Cells.h_min, jCell, DiffusionCoeff); var op = (Flux).Operator(DegreeOfNonlinearity: 2); // increase diffusion coefficient for next cycle if (DiffusionCoeff == 0) { DiffusionCoeff = 1.0e-3; // should this be minus or plus? } else { DiffusionCoeff *= 10; } op.ComputeMatrixEx(ExtProperty.Mapping, ArrayTools.Cat <DGField>(new DGField[] { ExtProperty, Phi }, GradPhi), ExtProperty.Mapping, this.m_ExtvelMatrix, this.m_ExtvelAffine, OnlyAffine: false, volQuadScheme: (new CellQuadratureScheme(true, cM)), edgeQuadScheme: (new EdgeQuadratureScheme(true, eM)), ParameterMPIExchange: false); // extract operator matrix and RHS // ------------------------------- // the matrix must only have entries in the block-diagonal! MultidimensionalArray Mtx = MultidimensionalArray.Create(N, N); //MultidimensionalArray rhs = MultidimensionalArray.Create(N); double[] rhs = new double[N]; for (int n = 0; n < N; n++) { #if DEBUG int Lr; int[] row_cols = null; double[] row_vals = null; Lr = this.m_ExtvelMatrix.GetRow(i0G + n, ref row_cols, ref row_vals); for (int lr = 0; lr < Lr; lr++) { int ColIndex = row_cols[lr]; double Value = row_vals[lr]; Debug.Assert((ColIndex >= i0G && ColIndex < i0G + N) || (Value == 0.0), "Matrix is expected to be block-diagonal."); } #endif for (int m = 0; m < N; m++) { Mtx[n, m] = this.m_ExtvelMatrix[i0G + n, i0G + m]; } rhs[n] = -this.m_ExtvelAffine[i0L + n]; } // Solve the system, i.e. the local extension-velocity equation // ------------------------------------------------------------ double[] ep = new double[N]; Mtx.Solve(ep, rhs); for (int n = 0; n < N; n++) { ExtProperty.Coordinates[jCell, n] = ep[n]; } // detect violation of maximum principle // ------------------------------------- ExtProperty.GetExtremalValuesInCell(out mini, out maxi, jCell); // define relaxed bounds... double compExtPropertyMin = ExtPropertyMin - (1.0e-8 + ExtPropertyMax - ExtPropertyMin) * 0.2; double compExtPropertyMax = ExtPropertyMax + (1.0e-8 + ExtPropertyMax - ExtPropertyMin) * 0.2; // test if extension velocity solution is within bounds MaximumPrincipleFulfilled = (mini >= compExtPropertyMin) && (maxi <= compExtPropertyMax); if (count > 5) { break; } } if (count > 4) { Console.WriteLine(" ExtVel, cell #{0}, Diff coeff {1}, extremal p. holds? {2} (min/max soll = {3:e4}/{4:e4}, ist = {5:e4}/{6:e4})", jCell, DiffusionCoeff, MaximumPrincipleFulfilled, ExtPropertyMin, ExtPropertyMax, mini, maxi); } // record maxima and minima // ======================== ExtPropertyMax = Math.Max(ExtPropertyMax, maxi); ExtPropertyMin = Math.Min(ExtPropertyMin, mini); }