/// <summary> /// Passes the given parameters to <see cref="INonlinEdgeForm_GradV.InternalEdge"/> /// </summary> /// <param name="prm"></param> /// <param name="U"></param> /// <param name="GradU"></param> /// <param name="f"></param> void INonlinVolumeForm_GradV.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { INonlinEdgeForm_GradV flux = fluxFunction; MultidimensionalArray[] UBoundary; MultidimensionalArray normals; EdgeFormParams efp; AdaptParameters(ref prm, U, GradU, out efp, out UBoundary, out normals); MultidimensionalArray[] GradUBoundary = GradU; // cf. SIPGFlux, line 206 // Set fBoundary to zero MultidimensionalArray fBoundary = MultidimensionalArray.Create( U[0].GetLength(0), prm.Xglobal.GetLength(1), CompressibleEnvironment.NumberOfDimensions); fluxFunction.AdiabaticWall = this.adiaWall; flux.InternalEdge(ref efp, U, UBoundary, GradU, GradUBoundary, f, fBoundary); }
/// <summary> /// Reformulates the given parameters into <paramref name="efp"/>, /// <paramref name="UBoundary"/> and <paramref name="normals"/>, which /// are in the form required by /// <see cref="INonlinEdgeForm_GradV.InternalEdge"/> /// and <see cref="INonlinEdgeForm_V.InternalEdge"/> /// </summary> /// <param name="prm"></param> /// <param name="U"></param> /// <param name="GradU"></param> /// <param name="efp"></param> /// <param name="UBoundary"></param> /// <param name="normals"></param> private void AdaptParameters(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, out EdgeFormParams efp, out MultidimensionalArray[] UBoundary, out MultidimensionalArray normals) { Debug.Assert(U[0].GetLength(0) == 1, "Number of cells must be 1"); Debug.Assert(prm.Len == 1, "Number of cells must be 1"); INonlinEdgeForm_GradV flux = fluxFunction; int noOfCells = 1; int noOfNodesPerCell = prm.Xglobal.GetLength(1); UBoundary = new MultidimensionalArray[U.Length]; for (int k = 0; k < U.Length; k++) { UBoundary[k] = MultidimensionalArray.Create(noOfCells, noOfNodesPerCell); } normals = MultidimensionalArray.Create( noOfCells, noOfNodesPerCell, CompressibleEnvironment.NumberOfDimensions); Material material = speciesMap.GetMaterial(double.NaN); for (int j = 0; j < noOfNodesPerCell; j++) { double[] x = new double[CompressibleEnvironment.NumberOfDimensions]; double[] normal = new double[CompressibleEnvironment.NumberOfDimensions]; double abs = 0.0; for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++) { x[d] = prm.Xglobal[0, j, d]; normal[d] = prm.ParameterVars[d][0, j]; abs += normal[d] * normal[d]; } abs = Math.Sqrt(abs); Debug.Assert(abs > 1e-10, "Extremely flat level set gradient"); for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++) { normal[d] /= abs; } StateVector stateIn = new StateVector(material, U, 0, j, CompressibleEnvironment.NumberOfDimensions); StateVector stateBoundary = boundaryCondition.GetBoundaryState( prm.time, x, normal, stateIn); Debug.Assert(stateBoundary.IsValid, "Invalid boundary state"); double[] UBoundaryLocal = stateBoundary.ToArray(); for (int k = 0; k < U.Length; k++) { UBoundary[k][0, j] = UBoundaryLocal[k]; } for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++) { normals[0, j, d] = normal[d]; } } efp = new EdgeFormParams() { e0 = Math.Abs(prm.GridDat.iLogicalCells.Cells2Edges[prm.j0][0]) - 1, // THIS IS AN EVIL HACK; NEEDS TO BE CHANGED GridDat = prm.GridDat, Len = prm.Len, NodesGlobal = prm.Xglobal, Normals = normals, ParameterVars_IN = prm.ParameterVars, ParameterVars_OUT = prm.ParameterVars, time = prm.time }; }