protected override void ComputeChangeRate(double[] k, double AbsTime, double RelTime, double[] edgeFluxes = null) { using (new ilPSP.Tracing.FuncTrace()) { RaiseOnBeforeComputechangeRate(AbsTime, RelTime); Evaluator.time = AbsTime; Evaluator.Evaluate(1.0, 0.0, k, outputBndEdge: edgeFluxes); Debug.Assert( !k.Any(f => double.IsNaN(f)), "Unphysical flux in standard terms"); //k.SaveToTextFile("k-lts-bulk.txt"); boundaryEvaluator.Value.time = AbsTime; boundaryEvaluator.Value.Evaluate(1.0, 1.0, k); Debug.Assert( !k.Any(f => double.IsNaN(f)), "Unphysical flux in boundary terms"); // Agglomerate fluxes speciesMap.Agglomerator.ManipulateRHS(k, Mapping); // Apply inverse to all cells with non-identity mass matrix IBMMassMatrixFactory massMatrixFactory = speciesMap.GetMassMatrixFactory(Mapping); IBMUtility.SubMatrixSpMV(massMatrixFactory.InverseMassMatrix, 1.0, k, 0.0, k, cutAndTargetCells); } }
public override double Perform(double dt) { if (agglomerationPatternHasChanged) { // TO DO: Agglomerate difference between old $cutAndTargetCells and new $cutAndTargetCells only BuildEvaluatorsAndMasks(); // Required whenever agglomeration pattern changes SpeciesId speciesId = speciesMap.Tracker.GetSpeciesId(speciesMap.Control.FluidSpeciesName); IBMMassMatrixFactory massMatrixFactory = speciesMap.GetMassMatrixFactory(Mapping); BlockMsrMatrix nonAgglomeratedMassMatrix = massMatrixFactory.BaseFactory.GetMassMatrix( Mapping, new Dictionary <SpeciesId, IEnumerable <double> >() { { speciesId, Enumerable.Repeat(1.0, Mapping.NoOfVariables) } }, inverse: false); IBMUtility.SubMatrixSpMV(nonAgglomeratedMassMatrix, 1.0, CurrentState, 0.0, CurrentState, cutCells); speciesMap.Agglomerator.ManipulateRHS(CurrentState, Mapping); IBMUtility.SubMatrixSpMV(massMatrixFactory.InverseMassMatrix, 1.0, CurrentState, 0.0, CurrentState, cutAndTargetCells); speciesMap.Agglomerator.Extrapolate(CurrentState.Mapping); //Broadcast to RungeKutta ??? } dt = base.Perform(dt); speciesMap.Agglomerator.Extrapolate(CurrentState.Mapping); return(dt); }
protected void AgglomerateAndExtrapolateDGCoordinates() { IBMMassMatrixFactory massMatrixFactory = speciesMap.GetMassMatrixFactory(Mapping); BlockMsrMatrix nonAgglomeratedMassMatrix = massMatrixFactory.NonAgglomeratedMassMatrix; IBMUtility.SubMatrixSpMV(nonAgglomeratedMassMatrix, 1.0, DGCoordinates, 0.0, DGCoordinates, cutCells); // eq. (39) speciesMap.Agglomerator.ManipulateRHS(DGCoordinates, Mapping); // eq. (39) IBMUtility.SubMatrixSpMV(massMatrixFactory.InverseMassMatrix, 1.0, DGCoordinates, 0.0, DGCoordinates, cutAndTargetCells); // eq. (39) speciesMap.Agglomerator.Extrapolate(DGCoordinates.Mapping); // eq. (41) }
protected override void ComputeChangeRate(double[] k, double AbsTime, double RelTime, double[] edgeFluxes = null) { Evaluator.Evaluate(1.0, 0.0, k, AbsTime, outputBndEdge: edgeFluxes); Debug.Assert( !k.Any(f => double.IsNaN(f)), "Unphysical flux in standard terms"); boundaryEvaluator.Value.Evaluate(1.0, 1.0, k, AbsTime); Debug.Assert( !k.Any(f => double.IsNaN(f)), "Unphysical flux in boundary terms"); // Agglomerate fluxes speciesMap.Agglomerator.ManipulateRHS(k, Mapping); // Apply inverse to all cells with non-identity mass matrix IBMMassMatrixFactory massMatrixFactory = speciesMap.GetMassMatrixFactory(Mapping); IBMUtility.SubMatrixSpMV(massMatrixFactory.InverseMassMatrix, 1.0, k, 0.0, k, cutAndTargetCells); }
internal static double GetMassMatrixDeterminant(ImmersedSpeciesMap speciesMap, CoordinateMapping mapping, CellMask cellMask) { BlockMsrMatrix massMatrix = speciesMap.GetMassMatrixFactory(mapping).MassMatrix; Basis maxBasis = mapping.BasisS.ElementAtMax(b => b.Degree); MultidimensionalArray subMatrix = MultidimensionalArray.Create( cellMask.NoOfItemsLocally + 1, maxBasis.Length, cellMask.NoOfItemsLocally + 1, maxBasis.Length); int cellIndex = 0; foreach (Chunk chunk in cellMask) { for (int i = 0; i < chunk.Len; i++) { //IMatrix block = massMatrix.GetBlock(i + chunk.i0); MultidimensionalArray block = GetBlock(massMatrix, i + chunk.i0); for (int j = 0; j < maxBasis.Length; j++) { for (int k = 0; k < maxBasis.Length; k++) { subMatrix[cellIndex, j, cellIndex, k] = block[j, k]; } } cellIndex++; } } for (int j = 0; j < maxBasis.Length; j++) { subMatrix[cellIndex, j, cellIndex, j] = 1.0; } subMatrix = subMatrix.ResizeShallow( (cellMask.NoOfItemsLocally + 1) * maxBasis.Length, (cellMask.NoOfItemsLocally + 1) * maxBasis.Length); return(subMatrix.cond()); }
internal static double GetMaxLocalMassMatrixDeterminant(ImmersedSpeciesMap speciesMap, CoordinateMapping mapping, CellMask cellMask, out int maxCondCell) { BlockMsrMatrix massMatrix = speciesMap.GetMassMatrixFactory(mapping).MassMatrix; Basis maxBasis = mapping.BasisS.ElementAtMax(b => b.Degree); MultidimensionalArray subMatrix = MultidimensionalArray.Create( maxBasis.Length, maxBasis.Length); double maxCond = 0.0; maxCondCell = -1; foreach (Chunk chunk in cellMask) { for (int i = 0; i < chunk.Len; i++) { //IMatrix block = massMatrix.GetBlock(i + chunk.i0); MultidimensionalArray block = GetBlock(massMatrix, i + chunk.i0); for (int j = 0; j < maxBasis.Length; j++) { for (int k = 0; k < maxBasis.Length; k++) { subMatrix[j, k] = block[j, k]; } } double cond = subMatrix.cond(); if (cond > maxCond) { maxCond = cond; maxCondCell = i + chunk.i0; } } } return(maxCond); }