protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { this.BcMap = new IncompressibleBoundaryCondMap(this.GridData, grid.GetBoundaryConfig(), PhysicsMode.Incompressible); // assemble system, create matrix // ------------------------------ int D = GridData.SpatialDimension; //double penalty_base = ((double)((U[0].Basis.Degree + 1) * (U[0].Basis.Degree + D))) / ((double)D); double penalty_base = 1.0; double penalty_factor = 1.2; // equation assembly // ----------------- string[] CodNames = D.ForLoop(i => "C" + i); Operator = new SpatialOperator(VariableNames.VelocityVector(D), new string[] { VariableNames.ViscosityMolecular }, CodNames, QuadOrderFunc.Linear()); for (int d = 0; d < D; d++) { if ((this.whichTerms & Terms.T1) != 0) { var flx1 = new swipViscosity_Term1(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx1.g_Diri_Override = this.solution.U; flx1.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx1); } if ((this.whichTerms & Terms.T2) != 0) { var flx2 = new swipViscosity_Term2(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx2.g_Diri_Override = this.solution.U; flx2.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx2); } if ((this.whichTerms & Terms.T3) != 0) { var flx3 = new swipViscosity_Term3(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx3.g_Diri_Override = this.solution.U; flx3.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx3); } } // */ Operator.Commit(); var map = this.U.Mapping; OperatorMtx = new MsrMatrix(map, map); Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map, OperatorMtx, this.bnd.CoordinateVector, volQuadScheme: null, edgeQuadScheme: null); // test for matrix symmetry // ======================== if (base.MPISize == 1) { double MatrixAssymmetry = OperatorMtx.SymmetryDeviation(); Console.WriteLine("Matrix asymmetry: " + MatrixAssymmetry); Assert.LessOrEqual(Math.Abs(MatrixAssymmetry), 1.0e-10); } } }
/// <summary> /// Declaration of the spatial operator /// </summary> protected override SpatialOperator GetOperatorInstance(int D) { // instantiate boundary condition mapping // ====================================== boundaryCondMap = new IncompressibleBoundaryCondMap(this.GridData, this.Control.BoundaryValues, PhysicsMode.Incompressible); // instantiate operator // ==================== string[] CodName = (new[] { "ResidualMomentumX", "ResidualMomentumY", "ResidualMomentumZ" }).GetSubVector(0, D).Cat("ResidualConti"); var op = new SpatialOperator( __DomainVar: VariableNames.VelocityVector(D).Cat(VariableNames.Pressure), __ParameterVar: VariableNames.GravityVector(D), __CoDomainVar: CodName, QuadOrderFunc: QuadOrderFunc.NonLinear(2)); op.LinearizationHint = LinearizationHint.GetJacobiOperator; // Temporal Operator // ================= var TempOp = new ConstantTemporalOperator(op, 0.0); // init with entire diagonal set to 0.0 op.TemporalOperator = TempOp; for (int d = 0; d < D; d++) { TempOp.SetDiagonal(CodName[d], Control.Density); // set momentum equation entries to density } // Pressure Reference // ================== // if there is no Dirichlet boundary condition, // the mean value of the pressure is free: op.FreeMeanValue[VariableNames.Pressure] = !boundaryCondMap.DirichletPressureBoundary; // Momentum Equation // ================= // convective part: { for (int d = 0; d < D; d++) { var comps = op.EquationComponents[CodName[d]]; var ConvBulk = new LocalLaxFriedrichsConvection(D, boundaryCondMap, d, Control.Density); comps.Add(ConvBulk); // bulk component } } // pressure part: { for (int d = 0; d < D; d++) { var comps = op.EquationComponents[CodName[d]]; var pres = new PressureGradientLin_d(d, boundaryCondMap); comps.Add(pres); // bulk component } } // viscous part: { for (int d = 0; d < D; d++) { var comps = op.EquationComponents[CodName[d]]; double penalty_bulk = this.Control.PenaltySafety; var Visc = new swipViscosity_Term1(penalty_bulk, d, D, boundaryCondMap, ViscosityOption.ConstantViscosity, constantViscosityValue: Control.Viscosity); comps.Add(Visc); // bulk component GradUTerm } } // Continuity equation // =================== { for (int d = 0; d < D; d++) { var src = new Divergence_DerivativeSource(d, D); var flx = new Divergence_DerivativeSource_Flux(d, boundaryCondMap); op.EquationComponents[CodName[D]].Add(src); op.EquationComponents[CodName[D]].Add(flx); } //IBM_Op.EquationComponents["div"].Add(new PressureStabilization(1, 1.0 / this.Control.PhysicalParameters.mu_A)); } // Gravity parameter // ================= op.ParameterFactories.Add(delegate(IReadOnlyDictionary <string, DGField> DomainVarFields) { return(D.ForLoop(d => (VariableNames.Gravity_d(d), this.Gravity[d] as DGField))); }); // commit & return // =============== op.Commit(); return(op); }