public void ComputeHeatFlux() { using (FuncTrace ft = new FuncTrace()) { int D = this.LsTrk.GridDat.SpatialDimension; for (int d = 0; d < D; d++) { this.HeatFlux[d].Clear(); foreach (var Spc in LsTrk.SpeciesNames) // loop over species... // shadow fields { DGField Temp_Spc = (this.Temperature.GetSpeciesShadowField(Spc)); double kSpc = 0.0; switch (Spc) { case "A": kSpc = -this.Control.ThermalParameters.k_A; break; case "B": kSpc = -this.Control.ThermalParameters.k_B; break; default: throw new NotSupportedException("Unknown species name '" + Spc + "'"); } this.HeatFlux[d].GetSpeciesShadowField(Spc).DerivativeByFlux(kSpc, Temp_Spc, d, this.LsTrk.Regions.GetSpeciesSubGrid(Spc)); } } this.HeatFlux.ForEach(F => F.CheckForNanOrInf(true, true, true)); } }
/// <summary> /// Includes assembly of the matrix. /// </summary> /// <param name="L"></param> protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { // create operator // =============== { double D = this.GridData.SpatialDimension; double penalty_base = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D; double penalty_factor = base.Control.penalty_poisson; BoundaryCondMap<BoundaryType> PoissonBcMap = new BoundaryCondMap<BoundaryType>(this.GridData, this.Control.BoundaryValues, "T"); LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T"); var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, ((GridData)(this.GridData)).Cells.cj, PoissonBcMap); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); } //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave); //Console.WriteLine("condition number: {0:0.####E-00} ",condNo); } }
/// <summary> /// Loads a time-step from the database. /// </summary> /// <remarks> /// By using this method, it is ensured that the loaded/returned fields /// have the same DG polynomial degree as in the database. /// </remarks> public IEnumerable <DGField> LoadFields(ITimestepInfo info, IGridData grdDat, IEnumerable <string> NameFilter = null) { using (var tr = new FuncTrace()) { // check // ===== if (!info.Grid.ID.Equals(grdDat.GridID)) { throw new ArgumentException("Mismatch in Grid."); } // Instantiate // ========== IEnumerable <DGField.FieldInitializer> F2LoadInfo; if (NameFilter != null) { F2LoadInfo = info.FieldInitializers.Where(fi => NameFilter.Contains(fi.Identification, (a, b) => a.Equals(b))); } else { F2LoadInfo = info.FieldInitializers; } IInitializationContext ic = info.Database.Controller.GetInitializationContext(info); var fields = F2LoadInfo.Select(fi => fi.Initialize(ic)).ToArray(); List <DGField> fieldsFlattened = new List <DGField>(); TimestepInfo.FlattenHierarchy(fieldsFlattened, fields); this.LoadFieldData(info, grdDat, fieldsFlattened); return(fieldsFlattened); } }
/// <summary> /// accumulates the derivative of DG field <paramref name="f"/> /// (along the <paramref name="d"/>-th axis) times <paramref name="alpha"/> /// to this field, i.e. <br/> /// this = this + <paramref name="alpha"/>* \f$ \frac{\partial}{\partial x_d} \f$ <paramref name="f"/>; /// </summary> /// <param name="f"></param> /// <param name="d"> /// 0 for the x-derivative, 1 for the y-derivative, 2 for the z-derivative /// </param> /// <param name="alpha"> /// scaling of <paramref name="f"/>; /// </param> /// <param name="em"> /// An optional restriction to the domain in which the derivative is computed (it may, e.g. /// be only required in boundary cells, so a computation over the whole domain /// would be a waste of computation power. A proper execution mask for this case would be e.g. /// <see cref="BoSSS.Foundation.Grid.GridData.BoundaryCells"/>.)<br/> /// if null, the computation is carried out in the whole domain /// </param> override public void Derivative(double alpha, DGField f, int d, CellMask em) { using (var tr = new FuncTrace()) { MPICollectiveWatchDog.Watch(csMPI.Raw._COMM.WORLD); if (this.Basis.Degree < f.Basis.Degree - 1) { throw new ArgumentException("cannot compute derivative because of incompatible basis functions.", "f"); } if (f.Basis.GetType() != this.Basis.GetType()) { throw new ArgumentException("cannot compute derivative because of incompatible basis functions.", "f"); } int D = GridDat.SpatialDimension; if (d < 0 || d >= D) { throw new ArgumentException("spatial dimension out of range.", "d"); } Quadrature.EdgeQuadratureScheme _qInsEdge; Quadrature.CellQuadratureScheme _qInsVol; { _qInsEdge = (new Quadrature.EdgeQuadratureScheme(false, EdgeMask.GetEmptyMask(this.GridDat))); _qInsVol = (new Quadrature.CellQuadratureScheme(true, em)); } var op = (new BrokenDerivativeForm(d)).Operator(1, g => _qInsEdge, g => _qInsVol); op.Evaluate(alpha, 1.0, f.Mapping, null, this.Mapping); } }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { // assemble system, create matrix // ------------------------------ var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData)); double D = this.GridData.SpatialDimension; double penalty_base = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D; double penalty_factor = base.Control.penalty_poisson; { // equation assembly // ----------------- tr.Info("creating sparse system..."); Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); Stopwatch stw = new Stopwatch(); stw.Start(); SpatialOperator LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T"); var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, this.GridData.Cells.cj, base.Control); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); #if DEBUG var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif LaplaceMtx = new BlockMsrMatrix(T.Mapping); LaplaceAffine = new double[T.Mapping.LocalLength]; LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, LaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); #if DEBUG LaplaceAffine.ClearEntries(); LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, RefLaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs(); ErrMtx.Acc(-1.0, LaplaceMtx); double err = ErrMtx.InfNorm(); double infNrm = LaplaceMtx.InfNorm(); Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm); Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed."); #endif //int q = LaplaceMtx._GetTotalNoOfNonZeros(); //tr.Info("finished: Number of non-zeros: " + q); stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave); //Console.WriteLine("condition number: {0:0.####E-00} ",condNo); } } }
/// <summary> /// The Infinity-Norm (maximum absolute row sum norm) of this matrix; /// </summary> /// <returns></returns> static public double InfNorm(this IMutableMatrixEx M) { using (var tr = new FuncTrace()) { double normLoc = 0; int L = M.RowPartitioning.LocalLength; int[] col = null; double[] val = null; int Lr; for (int i = 0; i < L; i++) { double rownrm = 0; Lr = M.GetRow(i + M.RowPartitioning.i0, ref col, ref val); for (int j = 0; j < Lr; j++) { rownrm += Math.Abs(val[j]); } normLoc = Math.Max(normLoc, rownrm); } //Console.WriteLine("local norm (R=" + M.RowPartitioning.Rank + ") = " + normLoc); //tr.Info("local norm " + normLoc); double normGlob = double.NaN; unsafe { csMPI.Raw.Allreduce((IntPtr)(&normLoc), (IntPtr)(&normGlob), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.MAX, csMPI.Raw._COMM.WORLD); } return(normGlob); } }
/// <summary> /// Updates the sensor value /// <see cref="ShockCapturing.IShockSensor.UpdateSensorValues(CNSFieldSet, ISpeciesMap, CellMask)"/> /// and the artificial viscosity value <see cref="Variables.ArtificialViscosity"/> in every cell /// </summary> /// <param name="program"></param> /// <param name="cellMask"></param> public void UpdateShockCapturingVariables(IProgram <CNSControl> program, CellMask cellMask) { using (var tr = new FuncTrace()) { // Update sensor program.Control.ShockSensor.UpdateSensorValues(program.WorkingSet.AllFields, program.SpeciesMap, cellMask); // Update sensor variable (not necessary as only needed for IO) using (new BlockTrace("ShockSensor.UpdateFunction", tr)) { var sensorField = program.WorkingSet.DerivedFields[Variables.ShockSensor]; Variables.ShockSensor.UpdateFunction(sensorField, program.SpeciesMap.SubGrid.VolumeMask, program); } // Update artificial viscosity variable using (new BlockTrace("ArtificialViscosity.UpdateFunction", tr)) { var avField = program.WorkingSet.DerivedFields[Variables.ArtificialViscosity]; Variables.ArtificialViscosity.UpdateFunction(avField, program.SpeciesMap.SubGrid.VolumeMask, program); } // Test //double sensorNorm = program.WorkingSet.DerivedFields[Variables.ShockSensor].L2Norm(); //double AVNorm = program.WorkingSet.DerivedFields[Variables.ArtificialViscosity].L2Norm(); //Console.WriteLine("\r\nThis is UpdateShockCapturingVariables"); //Console.WriteLine("SensorNeu: {0}", sensorNorm); //Console.WriteLine("AVNeu: {0}", AVNorm); } }
/// <summary> /// performs some timesteps /// </summary> protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { using (var ft = new FuncTrace()) { //PerformanceVsCachesize(); //SimplifiedPerformance(); //u.ProjectField((_2D)((x, y) => x+y)); //var f = new SinglePhaseField(u.Basis, "f"); //var sgrd = new SubGrid(new CellMask(this.GridDat, Chunk.GetSingleElementChunk(200))); //f.Clear(); //f.DerivativeByFlux(1.0, u, 0, sgrd, true); //Tecplot plt1 = new Tecplot(GridDat, true, false, 0); //plt1.PlotFields("ggg" , "Scalar Transport", phystime, u, f, mpi_rank); //base.TerminationKey = true; double dtCFL; if (this.GridData is GridData) { dtCFL = this.GridData.ComputeCFLTime(this.Velocity, 1.0e10); } else { Console.WriteLine("Nix CFL"); dtCFL = 1e-3; } if (dt <= 0) { // if dt <= 0, we're free to set the timestep on our own //base.NoOfTimesteps = -1; //dt = 1; base.NoOfTimesteps = 10; base.EndTime = 5.0; dtCFL *= 1.0 / (((double)u.Basis.Degree).Pow2()); } Console.Write("Timestp. #" + TimestepNo + " of " + base.NoOfTimesteps + " ... \t"); dt = dtCFL * 0.5; Timestepper.Perform(dt); // set mpi_rank int J = this.GridData.iLogicalCells.NoOfLocalUpdatedCells; double rank = GridData.MpiRank; for (int j = 0; j < J; j++) { mpi_rank.SetMeanValue(j, rank); } //dt = Timestepper.PerformAdaptive(1.0e2); Console.WriteLine("finished (dt = {0:0.###E-00}, CFL frac = {1:0.###E-00})!", dt, dt / dtCFL); return(dt); } }
public IEnumerable <IChunkRulePair <CellBoundaryQuadRule> > GetQuadRuleSet(ExecutionMask mask, int order) { using (var tr = new FuncTrace()) { if (mask != null && mask is CellMask == false) { throw new ArgumentException("Cell mask required", "mask"); } if (mask.MaskType != MaskType.Geometrical) { throw new ArgumentException("Expecting a geometrical mask."); } Stopwatch totalTimer = new Stopwatch(); Stopwatch projectionTimer = new Stopwatch(); Stopwatch optimizationTimer = new Stopwatch(); totalTimer.Start(); if (order != currentOrder) { cache.Clear(); SwitchOrder(order); } var result = new List <ChunkRulePair <CellBoundaryQuadRule> >(mask.NoOfItemsLocally); foreach (Chunk chunk in mask) { for (int i = 0; i < chunk.Len; i++) { int cell = chunk.i0 + i; if (cache.ContainsKey(cell)) { result.Add(new ChunkRulePair <CellBoundaryQuadRule>( Chunk.GetSingleElementChunk(cell), cache[cell])); continue; } optimizationTimer.Start(); CellBoundaryQuadRule optimizedRule = GetOptimizedRule(chunk.i0 + i, order); optimizationTimer.Stop(); cache.Add(cell, optimizedRule); result.Add(new ChunkRulePair <CellBoundaryQuadRule>( Chunk.GetSingleElementChunk(i + chunk.i0), optimizedRule)); } } totalTimer.Stop(); double totalTicks = (double)totalTimer.ElapsedTicks; double percentageProjection = Math.Round(projectionTimer.ElapsedTicks / totalTicks * 100, 2); double percentageOptimization = Math.Round(optimizationTimer.ElapsedTicks / totalTicks * 100, 2); tr.Info("Percentage spent on projection to surface: " + percentageProjection.ToString(NumberFormatInfo.InvariantInfo) + "%"); tr.Info("Percentage spent on optimization: " + percentageOptimization.ToString(NumberFormatInfo.InvariantInfo) + "%"); return(result); } }
/// <summary> /// Constructs the quadrature rules all edges of all cells in /// <paramref name="mask"/>. For edges that are not intersected by the /// zero iso-contour, standard Gaussian quadrature rules of /// sufficiently high order will be used. /// </summary> /// <param name="mask"> /// Cells for which quadrature rules shall be created /// </param> /// <param name="order"> /// Desired order of the moment-fitting system. Assuming that /// <see cref="edgeSurfaceRuleFactory"/> integrates the basis /// polynomials exactly over the zero iso-contour (which it usually /// doesn't!), the resulting quadrature rules will be exact up to this /// order. /// </param> /// <returns>A set of quadrature rules</returns> /// <remarks> /// Since the selected level set is generally discontinuous across cell /// boundaries, this method does not make use of the fact that /// neighboring cells share edges. That is, the optimization will be /// performed twice for each inner edge in <paramref name="mask"/>. /// </remarks> public IEnumerable <IChunkRulePair <CellBoundaryQuadRule> > GetQuadRuleSet(ExecutionMask mask, int order) { using (var tr = new FuncTrace()) { if (!(mask is CellMask)) { throw new ArgumentException("CellMask required", "mask"); } if (mask.MaskType != MaskType.Geometrical) { throw new ArgumentException("Expecting a geometrical mask."); } int noOfEdges = LevelSetData.GridDat.Grid.RefElements[0].NoOfFaces; CellMask tmpLogicalMask = new CellMask(mask.GridData, mask.GetBitMask(), MaskType.Logical); #if DEBUG CellMask differingCells = tmpLogicalMask.Except(this.LevelSetData.Region.GetCutCellMask4LevSet(this.levelSetIndex)); if (differingCells.NoOfItemsLocally > 0) { throw new ArgumentException("The provided mask has to be a sub-set of the cut cells. " + "Cells {0} are not in the CutCellMaks of this tracker.", differingCells.GetSummary()); } #endif subGrid = new SubGrid(tmpLogicalMask); localCellIndex2SubgridIndex = subGrid.LocalCellIndex2SubgridIndex; if (order != lastOrder) { cache.Clear(); SwitchOrder(order); } var result = new List <ChunkRulePair <CellBoundaryQuadRule> >(mask.NoOfItemsLocally); CellBoundaryQuadRule[] optimizedRules = GetOptimizedRules((CellMask)mask, order); int n = 0; foreach (Chunk chunk in mask) { foreach (int cell in chunk.Elements) { if (cache.ContainsKey(cell)) { result.Add(new ChunkRulePair <CellBoundaryQuadRule>( Chunk.GetSingleElementChunk(cell), cache[cell])); } else { cache.Add(cell, optimizedRules[n]); result.Add(new ChunkRulePair <CellBoundaryQuadRule>( Chunk.GetSingleElementChunk(cell), optimizedRules[n])); } n++; } } return(result); } }
/// <summary> /// Finite difference directional derivative Approximate f'(x) w /// C.T.Kelley, April 1, 2003 /// This code comes with no guarantee or warranty of any kind. /// </summary> /// <param name="SolutionVec">Solution point</param> /// <param name="w">Direction</param> /// <param name="f0">f0, usually has been calculated earlier</param> /// <param name="linearization">True if the Operator should be linearized and evaluated afterwards</param> /// <returns></returns> public double[] dirder(CoordinateVector SolutionVec, double[] currentX, double[] w, double[] f0, bool linearization = false) { using (var tr = new FuncTrace()) { double epsnew = 1E-7; int n = SolutionVec.Length; double[] fx = new double[f0.Length]; // Scale the step if (w.L2NormPow2().MPISum().Sqrt() == 0) { fx.Clear(); return(fx); } var normw = w.L2NormPow2().MPISum().Sqrt(); double xs = GenericBlas.InnerProd(currentX, w).MPISum() / normw; if (xs != 0) { epsnew = epsnew * Math.Max(Math.Abs(xs), 1) * Math.Sign(xs); } epsnew = epsnew / w.L2NormPow2().MPISum().Sqrt(); var del = currentX.CloneAs(); del.AccV(epsnew, w); double[] temp = new double[SolutionVec.Length]; temp.CopyEntries(SolutionVec); this.CurrentLin.TransformSolFrom(SolutionVec, del); // Just evaluate linearized operator //var OpAffineRaw = this.LinearizationRHS.CloneAs(); //this.CurrentLin.OperatorMatrix.SpMV(1.0, new CoordinateVector(SolutionVec.Mapping.Fields.ToArray()), 1.0, OpAffineRaw); //CurrentLin.TransformRhsInto(OpAffineRaw, fx); if (linearization == false) { EvaluateOperator(1.0, SolutionVec.Mapping.Fields, fx); } //else { // this.m_AssembleMatrix(out OpMtxRaw, out OpAffineRaw, out MassMtxRaw, SolutionVec.Mapping.Fields.ToArray(), true); // OpMtxRaw.SpMV(1.0, new CoordinateVector(SolutionVec.Mapping.Fields.ToArray()), 1.0, OpAffineRaw); // CurrentLin.TransformRhsInto(OpAffineRaw, fx); //} SolutionVec.CopyEntries(temp); // (f1 - f0) / epsnew fx.AccV(1, f0); fx.ScaleV(1 / epsnew); return(fx); } }
/// <summary> /// computes <see cref="LaplaceMtx"/> and <see cref="LaplaceAffine"/> /// </summary> private void UpdateMatrices() { using (var tr = new FuncTrace()) { // time measurement for matrix assembly Stopwatch stw = new Stopwatch(); stw.Start(); // console Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); // quadrature domain var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData, MaskType.Geometrical)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical)); #if DEBUG // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard) var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif using (new BlockTrace("SipMatrixAssembly", tr)) { LaplaceMtx = new BlockMsrMatrix(T.Mapping); LaplaceAffine = new double[T.Mapping.LocalLength]; LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, LaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); } #if DEBUG LaplaceAffine.ClearEntries(); LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, RefLaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs(); ErrMtx.Acc(-1.0, LaplaceMtx); double err = ErrMtx.InfNorm(); double infNrm = LaplaceMtx.InfNorm(); Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm); Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed."); #endif stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); //var JB = LapaceIp.GetFDJacobianBuilder(T.Mapping.Fields, null, T.Mapping, edgQrSch, volQrSch); //var JacobiMtx = new BlockMsrMatrix(T.Mapping); //var JacobiAffine = new double[T.Mapping.LocalLength]; //JB.ComputeMatrix(JacobiMtx, JacobiAffine); //double L2ErrAffine = GenericBlas.L2Dist(JacobiAffine, LaplaceAffine); //var ErrMtx2 = LaplaceMtx.CloneAs(); //ErrMtx2.Acc(-1.0, JacobiMtx); //double LinfErrMtx2 = ErrMtx2.InfNorm(); //JacobiMtx.SaveToTextFileSparse("D:\\tmp\\Jac.txt"); //LaplaceMtx.SaveToTextFileSparse("D:\\tmp\\Lap.txt"); //Console.WriteLine("FD Jacobi Mtx: {0:e14}, Affine: {1:e14}", LinfErrMtx2, L2ErrAffine); } }
/// <summary> /// Loads a time-step from the database into previously allocated /// DG-fields (<paramref name="PreAllocatedFields"/>). /// </summary> public void LoadFieldData(ITimestepInfo info, IGridData grdDat, IEnumerable <DGField> PreAllocatedFields) { using (var tr = new FuncTrace()) { DGField[] Fields = PreAllocatedFields.ToArray(); // enforce 'evaluation' of the enum (in the case it is some delayed linq-expr). List <DGField> FieldsFlatten = new List <DGField>(); TimestepInfo.FlattenHierarchy(FieldsFlatten, Fields); foreach (var f in FieldsFlatten) { if (!Fields.Contains(f, (a, b) => object.ReferenceEquals(a, b))) { throw new ArgumentException("Unable to load timestep: field '" + f.Identification + "', which is required by at least one of the given fields, must also be contained in the given list of fields.", "PreAllocatedFields"); } } // Load data vector // ================ var partition = grdDat.CellPartitioning; var DataVec = this.Driver.LoadVector <CellFieldDataSet>(info.StorageID, ref partition); // Permute data vector // =================== var SortedDataVec = new CellFieldDataSet[DataVec.Count]; { // tau is the GlobalID-permutation that we have for the loaded vector // sigma is the current GlobalID-permutation of the grid var sigma = grdDat.CurrentGlobalIdPermutation; var tau = new Permutation(DataVec.Select(cd => cd.GlobalID).ToArray(), csMPI.Raw._COMM.WORLD); // compute resorting permutation Permutation invSigma = sigma.Invert(); Permutation Resorting = invSigma * tau; tau = null; invSigma = null; // put dg coordinates into right order Resorting.ApplyToVector(DataVec, SortedDataVec); } // Load the fields // =============== HashSet <object> loadedObjects = new HashSet <object>(ReferenceComparer.Instance); foreach (var Field in Fields) { Field.LoadData(info, SortedDataVec, loadedObjects); } } }
/// <summary> /// % /// </summary> public void Solve <U, V>(U X, V B) where U : IList <double> where V : IList <double> // { using (var tr = new FuncTrace()) { using (var solver = GetSolver(m_Mtx)) { var result = solver.Solve(X, B); this.Converged = result.Converged; this.ThisLevelIterations += result.NoOfIterations; } } }
/// <summary> /// Loads the given <paramref name="sessionId"/> from the given /// <paramref name="database"/>. /// </summary> /// <param name="sessionId"></param> /// <param name="database"></param> /// <returns></returns> public SessionInfo LoadSession(Guid sessionId, IDatabaseInfo database) { using (var tr = new FuncTrace()) { tr.Info("Loading session " + sessionId); using (Stream s = fsDriver.GetSessionInfoStream(false, sessionId)) { SessionInfo loadedSession = (SessionInfo)Driver.Deserialize(s, typeof(SessionInfo)); loadedSession.Database = database; loadedSession.WriteTime = Utils.GetSessionFileWriteTime(loadedSession); s.Close(); return(loadedSession); } } }
public void Init(MultigridOperator op) { using (var tr = new FuncTrace()) { var Mtx = op.OperatorMatrix; var MgMap = op.Mapping; m_MultigridOp = op; if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } m_Mtx = Mtx; } }
/// <summary> /// Updates all derived variables within /// <see cref="CNSFieldSet.DerivedFields"/> using their corresponding /// update function <see cref="DerivedVariable.UpdateFunction"/> /// </summary> public void UpdateDerivedVariables(IProgram <CNSControl> program, CellMask cellMask) { using (var tr = new FuncTrace()) { program.Control.ShockSensor?.UpdateSensorValues(program.WorkingSet.AllFields, program.SpeciesMap, cellMask); foreach (var pair in DerivedFields) { using (new BlockTrace("UpdateFunction:" + pair.Value.Identification + "-" + pair.Key.Name, tr)) { pair.Key.UpdateFunction(pair.Value, cellMask, program); } } // Test //double sensorNorm = program.WorkingSet.DerivedFields[Variables.ShockSensor].L2Norm(); //double AVNorm = program.WorkingSet.DerivedFields[Variables.ArtificialViscosity].L2Norm(); //Console.WriteLine("\r\nThis is UpdateDerivedVariables"); //Console.WriteLine("SensorNeu: {0}", sensorNorm); //Console.WriteLine("AVNeu: {0}", AVNorm); } }
/// <summary> /// Loads a BoSSS grid from an grid file; the file type (see <see cref="ImporterTypes"/>) are determined by the file ending. /// </summary> public static GridCommons Import(string fileName) { using (var tr = new FuncTrace()) { ImporterTypes importerType = GetImporterType(fileName); tr.Info(string.Format("Loading {0} file '{1}'...", importerType.ToString(), fileName)); IGridImporter importer; using (new BlockTrace("Import", tr)) { switch (importerType) { case ImporterTypes.Gambit: GambitNeutral gn = new GambitNeutral(fileName); if (gn.BoSSSConversionNeccessary()) { gn = gn.ToLinearElements(); } importer = gn; break; case ImporterTypes.CGNS: importer = new Cgns(fileName); break; case ImporterTypes.Gmsh: importer = new Gmsh(fileName); break; default: throw new NotImplementedException(); } } tr.Info("Converting to BoSSS grid ..."); GridCommons grid; using (new BlockTrace("Conversion", tr)) { grid = importer.GenerateBoSSSGrid(); } return(grid); } }
/// <summary> /// Restriction of <paramref name="X"/> and <paramref name="B"/> to lower level, execution of <see cref="CoarserLevelSolver"/> and prolongation of coarse solution. /// </summary> public void Solve <U, V>(U X, V B) where U : IList <double> where V : IList <double> { // using (var tr = new FuncTrace()) { int N = this.m_OpThisLevel.CoarserLevel.Mapping.LocalLength; double[] xc = new double[N], bc = new double[N]; //this.RestrictionOperator.SpMVpara(1.0, X, 0.0, xc); //this.RestrictionOperator.SpMVpara(1.0, B, 0.0, bc); this.m_OpThisLevel.CoarserLevel.Restrict(B, bc); this.m_OpThisLevel.CoarserLevel.Restrict(X, xc); CoarserLevelSolver.Solve(xc, bc); //this.PrologateOperator.SpMV(1.0, xc, 0.0, X); this.m_OpThisLevel.CoarserLevel.Prolongate(1.0, X, 0.0, xc); } }
/// <summary> /// Loads the grid info object for the given /// <paramref name="gridGuid"/> from the given /// <paramref name="database"/> /// </summary> /// <param name="gridGuid"></param> /// <param name="database"></param> /// <returns></returns> public IGridInfo LoadGridInfo(Guid gridGuid, IDatabaseInfo database) { using (var tr = new FuncTrace()) { tr.Info("Loading grid " + gridGuid); IGrid grid = null; grid = DeserializeGrid(gridGuid); /* * if (MyRank == 0) * { * grid = DeserializeGrid(gridGuid); * } * * grid = grid.MPIBroadcast(0); */ grid.GridSerializationHandler.Database = database; grid.WriteTime = Utils.GetGridFileWriteTime(grid); return(grid); } }
/// <summary> /// /// </summary> /// <param name="create"> /// true: creates a new file for writing; /// false: open a file for reading; /// </param> /// <param name="RelPath"> /// relative path within the base paths. /// </param> /// <returns> /// a file stream /// </returns> /// <param name="ForceOverride"> /// when opening a stream for writing (<paramref name="create"/>=true), this argument /// toggles how existing files should be treated: /// false: an exception is thrown if the file already exists; /// true: an existing file would be overwritten /// </param> /// <returns></returns> private Stream OpenFile(bool create, string RelPath, bool ForceOverride) { using (var tr = new FuncTrace()) { tr.Info("opening file '" + RelPath + "', create='" + create + "'"); if (create) { // create new file string fullpath = Path.Combine(BasePath, RelPath); if (ForceOverride == true) { FileStream fs = new FileStream(fullpath, FileMode.Create); //, FileAccess.ReadWrite, FileShare.Read); // overwrites existing file return(fs); } else { FileStream fs = new FileStream(fullpath, FileMode.CreateNew);//, FileAccess.ReadWrite, FileShare.Read); // throws exception if file exists return(fs); } } else { // try to open file FileNotFoundException exc = null; try { FileStream fs = new FileStream(Path.Combine(BasePath, RelPath), FileMode.Open, FileAccess.Read, FileShare.Read); return(fs); } catch (FileNotFoundException fnf) { exc = fnf; } throw exc; } } }
/// <summary> /// loads a single <see cref="TimestepInfo"/>-object from the database. /// </summary> public TimestepInfo LoadTimestepInfo(Guid timestepGuid, ISessionInfo session, IDatabaseInfo database) { using (var tr = new FuncTrace()) { tr.Info("Loading time-step " + timestepGuid); TimestepInfo tsi = null; if (MyRank == 0) { using (Stream s = fsDriver.GetTimestepStream(false, timestepGuid)) { tsi = (TimestepInfo)Driver.Deserialize(s, typeof(TimestepInfo)); tsi.Session = session; s.Close(); } tsi.ID = timestepGuid; } tsi = tsi.MPIBroadcast(0); tsi.Database = database; tsi.WriteTime = Utils.GetTimestepFileWriteTime(tsi); return(tsi); } }
/// <summary> /// see <see cref="Device.CreateMatrix(MsrMatrix,MatrixType)"/>; /// </summary> public override MatrixBase CreateMatrix(MsrMatrix M, MatrixType matType) { using (var f = new FuncTrace()) { f.Info("desired matrix type: " + matType); switch (matType) { case MatrixType.CCBCSR: return(new CudaCCBCSRMatrix(M, this.Env)); case MatrixType.CSR: return(new CudaCSRMatrix(M, this.Env)); case MatrixType.ELLPACK: return(new CudaELLPACKmodMatrix(M, this.Env)); case MatrixType.Auto: case MatrixType.ELLPACKcache: return(new CudaELLPACKcacheMatrix(M, this.Env)); default: throw new NotImplementedException(); } } }
/// <summary> /// Includes assembly of the matrix. /// </summary> /// <param name="L"></param> protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { // create operator // =============== { double D = this.GridData.SpatialDimension; double penalty_base = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D; double penalty_factor = base.Control.penalty_poisson; BoundaryCondMap <BoundaryType> PoissonBcMap = new BoundaryCondMap <BoundaryType>(this.GridData, this.Control.BoundaryValues, "T"); LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T"); MultidimensionalArray LengthScales; if (this.GridData is GridData) { LengthScales = ((GridData)GridData).Cells.cj; } else if (this.GridData is AggregationGridData) { LengthScales = ((AggregationGridData)GridData).AncestorGrid.Cells.cj; } else { throw new NotImplementedException(); } var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, LengthScales, PoissonBcMap); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); } } }
/// <summary> /// /// </summary> protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { using (var tr = new FuncTrace()) { tr.Info("Performing time iteration No. " + TimestepNo); // Set dt and SIMPLEStatus switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: { dt = 0.0; break; } case SolutionAlgorithms.Unsteady_SIMPLE: { dt = SolverConf.dt; SIMPLEStatus.NextTimestep(); break; } } // some console-output if (base.MPIRank == 0) { switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: Console.WriteLine("Starting steady calculation...\n"); Console.WriteLine("Starting SIMPLE-Iterations...\n"); break; case SolutionAlgorithms.Unsteady_SIMPLE: Console.WriteLine("Starting time step #" + TimestepNo + "...\n"); Console.WriteLine("Starting SIMPLE-Iterations...\n"); break; default: throw new NotImplementedException(); } } do { // do one SIMPLE iteration SIMPLEStatus.NextSIMPLEIteration(); SIMPLEStep.OverallIteration(ref SIMPLEStatus, dt, ResLogger); TerminationKey = WorkingSet.CheckForNanOrInf(Control); if (TerminationKey) { m_Logger.Warn("Found Nan in some field."); if (base.MPIRank == 0) { Console.WriteLine("ERROR: Found Nan in some field."); } Console.ReadKey(); } if ((Control.PhysicsMode == PhysicsMode.LowMach) && (SolverConf.Control.As <LowMachSIMPLEControl>().EdgeTagsNusselt != null)) { CalculateNusselt(SIMPLEStatus.Timestep, base.GridData, WorkingSet.Temperature.Current, Control); } // save to database if (SIMPLEStatus.SaveStep) { SaveToDatabase(SIMPLEStatus.Timestep, phystime); } // calculate errors int QuadDegreePressure = 20; int QuadDegreeVel = 20; ResLogger.ComputeL2Error(WorkingSet.Pressure, Control.AnalyticPressure, QuadDegreePressure, "p_ana"); ResLogger.ComputeL2Error(WorkingSet.Velocity.Current[0], Control.AnalyticVelocityX, QuadDegreeVel, "u_ana"); ResLogger.ComputeL2Error(WorkingSet.Velocity.Current[1], Control.AnalyticVelocityY, QuadDegreeVel, "v_ana"); if (SolverConf.SpatialDimension == 3) { ResLogger.ComputeL2Error(WorkingSet.Velocity.Current[2], Control.AnalyticVelocityZ, QuadDegreeVel, "w_ana"); } switch (Control.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: LowMachSIMPLEControl lowMachConf = Control as LowMachSIMPLEControl; ResLogger.ComputeL2Error(WorkingSet.Temperature.Current, lowMachConf.AnalyticTemperature, QuadDegreeVel, "T_ana"); ResLogger.ComputeL2Error(WorkingSet.Rho, lowMachConf.AnalyticDensity, QuadDegreeVel, "Rho_ana"); break; case PhysicsMode.Multiphase: MultiphaseSIMPLEControl multiphaseConf = Control as MultiphaseSIMPLEControl; ResLogger.ComputeL2Error(WorkingSet.Phi.Current, multiphaseConf.AnalyticLevelSet, QuadDegreeVel, "Phi_ana"); ResLogger.ComputeL2Error(WorkingSet.Rho, multiphaseConf.AnalyticDensity, QuadDegreeVel, "Rho_ana"); break; default: throw new NotImplementedException(); } // terminate SIMPLE in case of divergence if (ResLogger.Residuals["L2Norm p'"] > 1.0E+10) { TerminationKey = true; } // push residual logger to next iteration switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: ResLogger.NextIteration(false); break; case SolutionAlgorithms.Unsteady_SIMPLE: ResLogger.NextIteration(true); break; default: throw new NotImplementedException(); } }while (!SIMPLEStatus.IsConverged && !SIMPLEStatus.TerminateSIMPLE && !TerminationKey); // determine cause for end of SIMPLE iterations if (SIMPLEStatus.IsConverged) { tr.Info("Solution converged."); } else if (SIMPLEStatus.TerminateSIMPLE) { if (SIMPLEStatus.SIMPLEStepNo == Control.MaxNoSIMPLEsteps) { SIMPLEStatus.CntMaxNoSIMPLEsteps++; m_Logger.Warn("MaxNoSIMPLEsteps are reached."); } else { m_Logger.Warn("Unknown reason for terminating SIMPLE iterations - should not happen."); } } else { m_Logger.Error("Solution diverged."); } // save the new timestep switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: break; case SolutionAlgorithms.Unsteady_SIMPLE: WorkingSet.Push(Control); ResLogger.NextTimestep(false); break; default: throw new NotImplementedException(); } // some console-output if (SIMPLEStatus.IsConverged) { Console.WriteLine("\nINFO: Done SIMPLE-Iterations - Solution converged.\n"); } else if (SIMPLEStatus.SIMPLEStepNo == Control.MaxNoSIMPLEsteps) { Console.WriteLine("\nWARNING: Done SIMPLE-Iterations - Maximum number of SIMPLE steps was reached.\n"); } else { Console.WriteLine("\nERROR: Calculation was terminated - Solution diverged.\n"); } switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: Console.WriteLine("Done steady calculation."); break; case SolutionAlgorithms.Unsteady_SIMPLE: Console.WriteLine("Done time step #" + TimestepNo + ".\n"); break; default: throw new NotImplementedException(); } //LogEnergyOrrSommerfeld(TimestepNo, phystime, dt); if (Control.EdgeTagsDragAndLift != null) { CalculateDragAndLift(phystime); } //Log temperature history tall cavity //LogTemperature(phystime, this.WorkingSet.Temperature.Current); return(dt); } }
/// <summary> /// Job status. /// </summary> public override void EvaluateStatus(string idToken, object optInfo, string DeployDir, out bool isRunning, out bool isTerminated, out int ExitCode) { using (var tr = new FuncTrace()) { int id = int.Parse(idToken); ISchedulerJob JD; //if (optInfo != null && optInfo is ISchedulerJob _JD) { // JD = _JD; //} else { using (new BlockTrace("Scheduler.OpenJob", tr)) { JD = Scheduler.OpenJob(id); } //} /* * the following seems really slow: * * * List<SchedulerJob> allFoundJobs = new List<SchedulerJob>(); * ISchedulerCollection allJobs; * using (new BlockTrace("Scheduler.GetJobList", tr)) { * allJobs = Scheduler.Get * } * int cc = allJobs.Count; * Console.WriteLine("MsHpcClient: " + cc + " jobs."); * tr.Logger.Info("list of " + cc + " jobs."); * using (new BlockTrace("ID_FILTERING", tr)) { * foreach (SchedulerJob sJob in allJobs) { * if (sJob.Id != id) * continue; * allFoundJobs.Add(sJob); * } * * if (allFoundJobs.Count <= 0) { * // some weird state * isRunning = false; * isTerminated = false; * ExitCode = int.MinValue; * return; * } * } * * SchedulerJob JD; * using (new BlockTrace("SORTING", tr)) { * JD = allFoundJobs.ElementAtMax(MsHpcJob => MsHpcJob.SubmitTime); * } */ using (new BlockTrace("TASK_FILTERING", tr)) { ISchedulerCollection tasks = JD.GetTaskList(null, null, false); ExitCode = int.MinValue; foreach (ISchedulerTask t in tasks) { DeployDir = t.WorkDirectory; ExitCode = t.ExitCode; } } using (new BlockTrace("STATE_EVAL", tr)) { switch (JD.State) { case JobState.Configuring: case JobState.Submitted: case JobState.Validating: case JobState.ExternalValidation: case JobState.Queued: isRunning = false; isTerminated = false; break; case JobState.Running: case JobState.Finishing: isRunning = true; isTerminated = false; break; case JobState.Finished: isRunning = false; isTerminated = true; break; case JobState.Failed: case JobState.Canceled: case JobState.Canceling: isRunning = false; isTerminated = true; break; default: throw new NotImplementedException("Unknown job state: " + JD.State); } } } }
//bool solveVelocity = true; //double VelocitySolver_ConvergenceCriterion = 1e-5; //double StressSolver_ConvergenceCriterion = 1e-5; override public void SolverDriver <S>(CoordinateVector SolutionVec, S RHS) { using (var tr = new FuncTrace()) { // initial guess and its residual // ============================== double[] Solution, Residual; using (new BlockTrace("Slv Init", tr)) { base.Init(SolutionVec, RHS, out Solution, out Residual); } double[] Correction = new double[Solution.Length]; double ResidualNorm = Residual.L2NormPow2().MPISum().Sqrt(); int NoOfIterations = 0; if (m_LinearSolver.GetType() == typeof(SoftGMRES)) { ((SoftGMRES)m_LinearSolver).m_SessionPath = m_SessionPath; } OnIterationCallback(NoOfIterations, Solution.CloneAs(), Residual.CloneAs(), this.CurrentLin); if (CoupledIteration_Converged == null) { CoupledIteration_Converged = delegate() { return(true); } } ; int NoOfCoupledIteration = 0; if (Iteration_Count == null) { Iteration_Count = delegate(int NoIter, ref int coupledIter) { return(NoIter + 1); } } ; //int[] Velocity_idx = SolutionVec.Mapping.GetSubvectorIndices(false, 0, 1, 2); //int[] Stresses_idx = SolutionVec.Mapping.GetSubvectorIndices(false, 3, 4, 5); //int[] Velocity_fields = new int[] { 0, 1, 2 }; //int[] Stress_fields = new int[] { 3, 4, 5 }; //int NoCoupledIterations = 10; // iterate... // ========== //int NoOfMainIterations = 0; using (new BlockTrace("Slv Iter", tr)) { while ((!(ResidualNorm < ConvCrit && CoupledIteration_Converged()) && NoOfIterations < MaxIter && NoOfCoupledIteration < MaxCoupledIter) || (NoOfIterations < MinIter)) { NoOfIterations = Iteration_Count(NoOfIterations, ref NoOfCoupledIteration); //Console.WriteLine("NoOfIterations = {0}", NoOfIterations); //DirectSolver ds = new DirectSolver(); //ds.Init(this.CurrentLin); //double L2_Res = Residual.L2Norm(); this.m_LinearSolver.Init(this.CurrentLin); Correction.ClearEntries(); if (Correction.Length != Residual.Length) { Correction = new double[Residual.Length]; } this.m_LinearSolver.Solve(Correction, Residual); //if (NoOfIterations > NoCoupledIterations) //{ // if (solveVelocity) // { // Console.WriteLine("stress correction = 0"); // foreach (int idx in Stresses_idx) // { // Correction[idx] = 0.0; // } // } // else // { // Console.WriteLine("velocity correction = 0"); // foreach (int idx in Velocity_idx) // { // Correction[idx] = 0.0; // } // } //} // Residual may be invalid from now on... Solution.AccV(UnderRelax, Correction); // transform solution back to 'original domain' // to perform the linearization at the new point... // (and for Level-Set-Updates ...) this.CurrentLin.TransformSolFrom(SolutionVec, Solution); // update linearization base.Update(SolutionVec.Mapping.Fields, ref Solution); // residual evaluation & callback base.EvalResidual(Solution, ref Residual); ResidualNorm = Residual.L2NormPow2().MPISum().Sqrt(); //if (NoOfIterations > NoCoupledIterations) //{ // double coupledL2Res = 0.0; // if (solveVelocity) // { // foreach (int idx in Velocity_idx) // { // coupledL2Res += Residual[idx].Pow2(); // } // } // else // { // foreach (int idx in Stresses_idx) // { // coupledL2Res += Residual[idx].Pow2(); // } // } // coupledL2Res = coupledL2Res.Sqrt(); // Console.WriteLine("coupled residual = {0}", coupledL2Res); // if (solveVelocity && coupledL2Res < this.VelocitySolver_ConvergenceCriterion) // { // Console.WriteLine("SolveVelocity = false"); // this.solveVelocity = false; // } // else if (!solveVelocity && coupledL2Res < this.StressSolver_ConvergenceCriterion) // { // Console.WriteLine("SolveVelocity = true"); // this.solveVelocity = true; // } //} OnIterationCallback(NoOfIterations, Solution.CloneAs(), Residual.CloneAs(), this.CurrentLin); } } } } } }
private void ComputeAverageU <T>(IEnumerable <T> U0, VectorField <XDGField> U0mean, int order, XQuadSchemeHelper qh) where T : DGField { using (FuncTrace ft = new FuncTrace()) { var CC = this.LsTrk.Regions.GetCutCellMask(); int D = this.LsTrk.GridDat.SpatialDimension; double minvol = Math.Pow(this.LsTrk.GridDat.Cells.h_minGlobal, D); //var qh = new XQuadSchemeHelper(agg); foreach (var Spc in this.LsTrk.SpeciesIdS) // loop over species... //var Spc = this.LsTrk.GetSpeciesId("B"); { // shadow fields { DGField[] U0_Spc = U0.Select(U0_d => (U0_d is XDGField) ? ((DGField)((U0_d as XDGField).GetSpeciesShadowField(Spc))) : ((DGField)U0_d)).ToArray(); var U0mean_Spc = U0mean.Select(U0mean_d => U0mean_d.GetSpeciesShadowField(Spc)).ToArray(); // normal cells: for (int d = 0; d < D; d++) { U0mean_Spc[d].AccLaidBack(1.0, U0_Spc[d], this.LsTrk.Regions.GetSpeciesMask(Spc)); } // cut cells var scheme = qh.GetVolumeQuadScheme(Spc, IntegrationDomain: this.LsTrk.Regions.GetCutCellMask()); var rule = scheme.Compile(this.LsTrk.GridDat, order); CellQuadrature.GetQuadrature(new int[] { D + 1 }, // vector components: ( avg_vel[0], ... , avg_vel[D-1], cell_volume ) this.LsTrk.GridDat, rule, delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { EvalResult.Clear(); for (int d = 0; d < D; d++) { U0_Spc[d].Evaluate(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, d)); } var Vol = EvalResult.ExtractSubArrayShallow(-1, -1, D); Vol.SetAll(1.0); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { int jCell = i + i0; double Volume = ResultsOfIntegration[i, D]; if (Math.Abs(Volume) < minvol * 1.0e-12) { // keep current value // since the volume of species 'Spc' in cell 'jCell' is 0.0, the value in this cell should have no effect } else { for (int d = 0; d < D; d++) { double IntVal = ResultsOfIntegration[i, d]; U0mean_Spc[d].SetMeanValue(jCell, IntVal / Volume); } } } }).Execute(); } #if DEBUG { var Uncut = LsTrk.Regions.GetCutCellMask().Complement(); VectorField <SinglePhaseField> U0mean_check = new VectorField <SinglePhaseField>(D, new Basis(LsTrk.GridDat, 0), SinglePhaseField.Factory); for (int d = 0; d < D; d++) { U0mean_check[d].ProjectField(1.0, U0.ElementAt(d).Evaluate, new CellQuadratureScheme(false, Uncut).AddFixedOrderRules(LsTrk.GridDat, U0.ElementAt(d).Basis.Degree + 1)); } foreach (var _Spc in this.LsTrk.SpeciesIdS) // loop over species... { for (int d = 0; d < D; d++) { U0mean_check[d].AccLaidBack(-1.0, U0mean[d].GetSpeciesShadowField(_Spc), Uncut.Intersect(LsTrk.Regions.GetSpeciesMask(_Spc))); } } double checkNorm = U0mean_check.L2Norm(); Debug.Assert(checkNorm < 1.0e-6); } #endif U0mean.ForEach(F => F.CheckForNanOrInf(true, true, true)); } }
public SolverResult Solve <Tdiag, Tunknowns, Trhs>(double Scale, Tdiag d, Tunknowns x, Trhs rhs) where Tdiag : System.Collections.Generic.IList <double> where Tunknowns : System.Collections.Generic.IList <double> where Trhs : System.Collections.Generic.IList <double> { using (var tr = new FuncTrace()) { // check input arguments // ===================== if (x.Count != m_OrgMatrix.RowPartitioning.LocalLength) { throw new ArgumentException("length of x must be equal to matrix size."); } if (rhs.Count != m_OrgMatrix.RowPartitioning.LocalLength) { throw new ArgumentException("length of rhs must be equal to matrix size."); } if (Math.Abs(Scale) <= double.Epsilon) { throw new ArgumentException("scale to small."); } // prepare vectors // =============== double[] _x; double[] _rhs; if (x.GetType() == typeof(double[])) { _x = x as double[]; } else { _x = new double[x.Count]; } if (rhs.GetType() == typeof(double[])) { _rhs = (double[])((ICloneable)rhs).Clone(); } else { int L = m_MumpsMatrix.RowPart.LocalLength; _rhs = new double[L]; for (int i = 0; i < L; i++) { _rhs[i] = rhs[i]; } } // define matrix // ============= IMutableMatrixEx Mtx; //bool throwAwayMtx; if (d != null || Scale != 1.0) { // not very efficient, but _I_dont_care_ ! MsrMatrix _Mtx = new MsrMatrix(m_OrgMatrix); Mtx = _Mtx; _Mtx.Scale(Scale); int dLen = d.Count, L = _Mtx.RowPartitioning.LocalLength, i0 = (int)(_Mtx.RowPartitioning.i0); if ((L % dLen) != 0) { throw new ApplicationException("wrong length of 'd'."); } for (int l = 0; l < L; l++) { _Mtx[i0 + l, i0 + l] += d[l % dLen]; } //throwAwayMtx = true; } else { //throwAwayMtx = false; Mtx = m_OrgMatrix; } // call solver // =========== SolverResult r = new SolverResult(); using (new BlockTrace("CALL SOLVER", tr)) { r.Converged = true; r.NoOfIterations = 1; Stopwatch st = new Stopwatch(); st.Reset(); double[] gath_x, gath_b; GatherOnProc0(_x, _rhs, out gath_x, out gath_b); r.NoOfIterations = 1; int rank; int size; csMPI.Raw.Comm_Rank(this.m_MPI_Comm, out rank); csMPI.Raw.Comm_Size(this.m_MPI_Comm, out size); r.Converged = MUMPSInitAndSolve(m_OrgMatrix, gath_b); csMPI.Raw.Barrier(this.m_MPI_Comm); unsafe { bool snd = r.Converged; csMPI.Raw.Bcast((IntPtr)(&snd), 1, csMPI.Raw._DATATYPE.BYTE, 0, this.m_MPI_Comm); r.Converged = snd; } ScatterFromProc0(_x, gath_b); if (x.GetType() == typeof(double[])) { // do nothing } else { x.SetV(_x); } csMPI.Raw.Barrier(this.m_MPI_Comm); st.Stop(); r.RunTime = st.Elapsed; } return(r); } }
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); } } }