private void InitGlobals(VolumFormParams efp, int __K) { D = efp.GridDat.SpatialDimension; K = __K; L = efp.Len; NoArgs = this.ArgumentOrdering.Count; NoParams = this.ParameterOrdering != null ? this.ParameterOrdering.Count : 0; u = new double[NoArgs]; Grad_u = new double[NoArgs, D]; Grad_v = new double[D]; }
/// <summary> /// see <see cref="IVolumeForm_GradUxGradV.Form"/> /// </summary> void IVolumeForm_GradUxGradV.Form(ref VolumFormParams prm, MultidimensionalArray GradUxGradV) { Debug.Assert(prm.Len == GradUxGradV.GetLength(0)); int L = prm.Len; int __K = GradUxGradV.GetLength(1); // no of nodes Debug.Assert(GradUxGradV.GetLength(2) == this.ArgumentOrdering.Count); int D = GradUxGradV.GetLength(3); int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count; int _NOargs = this.ArgumentOrdering.Count; this.InitGlobals(prm, __K); CommonParamsVol cpv; cpv.GridDat = prm.GridDat; cpv.Parameters = new double[_NOParams]; cpv.Xglobal = new double[D]; cpv.time = prm.time; for (int l = 0; l < L; l++) // loop over cells... { cpv.jCell = prm.j0 + l; for (int k = 0; k < __K; k++) // loop over nodes... { for (int np = 0; np < _NOParams; np++) { cpv.Parameters[np] = prm.ParameterVars[np][l, k]; } for (int d = 0; d < D; d++) { cpv.Xglobal[d] = prm.Xglobal[l, k, d]; } for (int c = 0; c < _NOargs; c++) // loop over trial (codomain) variable components... { for (int e = 0; e < D; e++) // trial variable spatial direction { for (int d = 0; d < D; d++) // test variable spatial direction { GradUxGradV[l, k, c, d, e] = GetCoeff(ref this.Grad_u[c, e], ref this.Grad_v[d], ref cpv); } } } } } }
void IVolumeForm_UxV.Form(ref VolumFormParams prm, MultidimensionalArray UxV) { Debug.Assert(prm.Len == UxV.GetLength(0)); int L = prm.Len; int __K = UxV.GetLength(1); // no of nodes Debug.Assert(UxV.GetLength(2) == this.ArgumentOrdering.Count); int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count; int _NOargs = this.ArgumentOrdering.Count; this.InitGlobals(prm, __K); int D = prm.GridDat.SpatialDimension; CommonParamsVol cpv; cpv.GridDat = prm.GridDat; cpv.Parameters = new double[_NOParams]; cpv.Xglobal = new Vector(D); cpv.time = prm.time; for (int l = 0; l < L; l++) // loop over cells... { cpv.jCell = prm.j0 + l; for (int k = 0; k < __K; k++) // loop over nodes... { for (int np = 0; np < _NOParams; np++) { cpv.Parameters[np] = prm.ParameterVars[np][l, k]; } for (int d = 0; d < D; d++) { cpv.Xglobal[d] = prm.Xglobal[l, k, d]; } for (int c = 0; c < _NOargs; c++) // loop over trial (codomain) variable components... { UxV[l, k, c] = GetCoeff(ref this.u[c], ref this.v, ref cpv); } } } }
/// <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); }
void IVolumeSource_GradV.Form(ref VolumFormParams prm, MultidimensionalArray GradV) { Debug.Assert(prm.Len == GradV.GetLength(0)); int L = prm.Len; int __K = GradV.GetLength(1); // no of nodes int D = prm.GridDat.SpatialDimension; Debug.Assert(D == GradV.GetLength(2)); int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count; this.InitGlobals(prm, __K); CommonParamsVol cpv; cpv.GridDat = prm.GridDat; cpv.Parameters = new double[_NOParams]; cpv.Xglobal = new double[D]; cpv.time = prm.time; for (int l = 0; l < L; l++) // loop over cells... { cpv.jCell = prm.j0 + l; for (int k = 0; k < __K; k++) // loop over nodes... { for (int d = 0; d < D; d++) { cpv.Xglobal[d] = prm.Xglobal[l, k, d]; } for (int np = 0; np < _NOParams; np++) { cpv.Parameters[np] = prm.ParameterVars[np][l, k]; } for (int d = 0; d < D; d++) // test variable spatial direction { GradV[l, k, d] += GetCoeff(ref this.Grad_v[d], ref cpv); } } } }
void INonlinVolumeForm_GradV.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { int NumofCells = prm.Len; Debug.Assert(f.GetLength(0) == NumofCells); int NumOfNodes = f.GetLength(1); // no of nodes per cell for (int cell = 0; cell < NumofCells; cell++) // loop over cells... { for (int node = 0; node < NumOfNodes; node++) // loop over nodes... { double viscosity = prm.ParameterVars[0][cell, node]; for (int d = 0; d < GridData.SpatialDimension; d++) { f[cell, node, d] += viscosity * GradU[0][cell, node, d]; } } } }
void INonlinVolumeForm_GradV.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { int NumofCells = prm.Len; Debug.Assert(f.GetLength(0) == NumofCells); int NumOfNodes = f.GetLength(1); // no of nodes per cell for (int cell = 0; cell < NumofCells; cell++) // loop over cells... { for (int node = 0; node < NumOfNodes; node++) // loop over nodes... { double viscosity = prm.ParameterVars[0][cell, node]; for (int d = 0; d < dimension; d++) { //acc -= GradU[0, d] * GradV[d] * this.Nu(cpv.Xglobal, cpv.Parameters, cpv.jCell) * this.m_alpha; f[cell, node, d] += viscosity * GradU[0][cell, node, d]; } } } }
/// <summary> /// Passes the given parameters to <see cref="INonlinEdgeForm_V.InternalEdge"/> /// </summary> /// <param name="prm"></param> /// <param name="U"></param> /// <param name="GradU"></param> /// <param name="f"></param> void INonlinVolumeForm_V.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { INonlinEdgeForm_V 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)); OptimizedSIPGEnergyFlux.EVIL_HACK_CELL_INDEX = prm.j0; OptimizedSIPGMomentumFlux.EVIL_HACK_CELL_INDEX = prm.j0; fluxFunction.AdiabaticWall = this.adiaWall; flux.InternalEdge(ref efp, U, UBoundary, GradU, GradUBoundary, f, fBoundary); OptimizedSIPGEnergyFlux.EVIL_HACK_CELL_INDEX = -1; OptimizedSIPGMomentumFlux.EVIL_HACK_CELL_INDEX = -1; }
void INonlinVolumeForm_GradV.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { // Do Nothing }
void INonlinVolumeForm_GradV.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { int NumofCells = prm.Len; Debug.Assert(f.GetLength(0) == NumofCells); int NumOfNodes = f.GetLength(1); // no of nodes per cell int NumOfArguments = this.ArgumentOrdering.Count; Debug.Assert(NumOfArguments == U.Length); Debug.Assert(NumOfArguments == GradU.Length); double[,] GradU_in = new double[dimension, NumOfArguments]; double[] U_in = new double[NumOfArguments]; for (int cell = 0; cell < NumofCells; cell++) // loop over cells... { int jCell = prm.j0 + cell; for (int node = 0; node < NumOfNodes; node++) // loop over nodes... { for (int na = 0; na < NumOfArguments; na++) { U_in[na] = U[na][cell, node]; for (int d = 0; d < dimension; d++) { GradU_in[d, na] = GradU[na][cell, node, d]; } } unsafe { fixed(double *pGin = GTensorIn) { UpdateTensorComponent(U_in, dimension, pGin, material, cell); } } //UpdateTensorComponent(U_in, dimension, GTensorIn, material); //for (int k = 0; k < dimension; k++) { // for (int l = 0; l < dimension; l++) { // for (int j = 0; j < NumOfArguments; j++) { // f[cell, node, k] += GTensorIn[k, l, j] * GradU_in[l,j]; // } // } //} unsafe { fixed(double *pGin = GTensorIn, pGradUin = GradU_in) { double *pGinVar = pGin; for (int k = 0; k < dimension; k++) { double acc = 0; double *pGradUinVar = pGradUin; for (int l = 0; l < dimension; l++) { for (int j = 0; j < NumOfArguments; j++) { acc += *pGinVar * *pGradUinVar; //Increment Pointer pGinVar++; pGradUinVar++; } } f[cell, node, k] += acc; } } } } } #endregion }
/// <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 }; }
void INonlinVolumeForm_V.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { int L = prm.Len; Debug.Assert(f.GetLength(0) == L); int K = f.GetLength(1); // no of nodes per cell int D = prm.GridDat.SpatialDimension; int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count; Debug.Assert(_NOParams == prm.ParameterVars.Length); int _NOargs = this.ArgumentOrdering.Count; Debug.Assert(_NOargs == U.Length); Debug.Assert(_NOargs == GradU.Length); CommonParamsVol cpv; cpv.GridDat = prm.GridDat; cpv.Parameters = new double[_NOParams]; cpv.Xglobal = new double[D]; cpv.time = prm.time; double[] _GradV = new double[D]; double[,] _GradU = new double[_NOargs, D]; double[] _U = new double[_NOargs]; double _V = 1.0; for (int l = 0; l < L; l++) // loop over cells... { cpv.jCell = prm.j0 + l; for (int k = 0; k < K; k++) // loop over nodes... { for (int np = 0; np < _NOParams; np++) { cpv.Parameters[np] = prm.ParameterVars[np][l, k]; } for (int d = 0; d < D; d++) { cpv.Xglobal[d] = prm.Xglobal[l, k, d]; } for (int na = 0; na < _NOargs; na++) { if (U[na] != null) { _U[na] = U[na][l, k]; } if (GradU[na] != null) { for (int d = 0; d < D; d++) { _GradU[na, d] = GradU[na][l, k, d]; } } } f[l, k] += volForm.VolumeForm(ref cpv, _U, _GradU, _V, _GradV); } } }
void INonlinVolumeForm_GradV.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { int L = prm.Len; Debug.Assert(f.GetLength(0) == L); int K = f.GetLength(1); // no of nodes per cell int D = prm.GridDat.SpatialDimension; int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count; Debug.Assert(_NOParams == prm.ParameterVars.Length); int _NOargs = this.ArgumentOrdering.Count; Debug.Assert(_NOargs == U.Length); Debug.Assert(_NOargs == GradU.Length); CommonParamsVol cpv; cpv.GridDat = prm.GridDat; cpv.Parameters = new double[_NOParams]; cpv.Xglobal = new double[D]; cpv.time = prm.time; double[] _GradV = new double[D]; double[,] _GradU = new double[_NOargs, D]; double[] _U = new double[_NOargs]; double _V = 0.0; //unsafe { // fixed(double* pParameters = cpv.Parameters, p_U = _U, p_GradU = _GradU, p_GradV = _GradV) { //bool* pUisNull = stackalloc bool[_NOargs]; //bool* pGradUisNull = stackalloc bool[_NOargs]; //for(int na = 0; na < _NOargs; na++) { // pUisNull[na] = (U[na] != null); // pGradUisNull[na] = (GradU[na] != null); //} // unsafe opt bringt hier relativ wenig/nix for (int l = 0; l < L; l++) // loop over cells... { cpv.jCell = prm.j0 + l; for (int k = 0; k < K; k++) // loop over nodes... { for (int d = 0; d < D; d++) { cpv.Xglobal[d] = prm.Xglobal[l, k, d]; } for (int np = 0; np < _NOParams; np++) { cpv.Parameters[np] = prm.ParameterVars[np][l, k]; } /* * bool* ppUisNull = pUisNull; * bool* ppGradUisNull = pGradUisNull; * double* pp_U = p_U, pp_GradU = p_GradU; * for(int na = 0; na < _NOargs; na++) { * if(*ppUisNull) { * pp_U = U[na][l, k]; * } else { * pp_U = double.NaN; * } * pp_U++; * if(*ppGradUisNull) { * for(int d = 0; d < D; d++) { * pp_GradU = GradU[na][l, k, d]; * pp_GradU++; * } * } else { * for(int d = 0; d < D; d++) { * pp_GradU = double.NaN; * pp_GradU++; * } * } * ppUisNull++; * ppGradUisNull++; * } */ for (int na = 0; na < _NOargs; na++) { if (U[na] != null) { _U[na] = U[na][l, k]; } else { _U[na] = double.NaN; } if (GradU[na] != null) { for (int d = 0; d < D; d++) { _GradU[na, d] = GradU[na][l, k, d]; } } else { for (int d = 0; d < D; d++) { _GradU[na, d] = double.NaN; } } } /* * double* pp_GradV = p_GradV; * for(int d = 0; d < D; d++) { * pp_GradV = 1.0; * f[l, k, d] += volForm.VolumeForm(ref cpv, _U, _GradU, _V, _GradV); * pp_GradV = 0.0; * pp_GradV++; * } */ for (int d = 0; d < D; d++) { _GradV[d] = 1.0; f[l, k, d] += volForm.VolumeForm(ref cpv, _U, _GradU, _V, _GradV); _GradV[d] = 0.0; } } } }
void INonlinVolumeForm_V.Form(ref VolumFormParams prm, MultidimensionalArray[] U, MultidimensionalArray[] GradU, MultidimensionalArray f) { int L = prm.Len; Debug.Assert(f.GetLength(0) == L); int K = f.GetLength(1); // no of nodes per cell int D = prm.GridDat.SpatialDimension; int _NOParams = this.ParameterOrdering == null ? 0 : this.ParameterOrdering.Count; Debug.Assert(_NOParams == prm.ParameterVars.Length); int _NOargs = this.ArgumentOrdering.Count; Debug.Assert(_NOargs == U.Length); Debug.Assert(_NOargs == GradU.Length); CommonParamsVol cpv; cpv.GridDat = prm.GridDat; cpv.Parameters = new double[_NOParams]; cpv.Xglobal = new Vector(D); cpv.time = prm.time; double[] _GradV = new double[D]; double[,] _GradU = new double[_NOargs, D]; double[] _U = new double[_NOargs]; double _V = 1.0; #if DEBUG MultidimensionalArray f_check = null; if (volForm is INonlinVolumeForm_V volForm_) { f_check = f.CloneAs(); volForm_.Form(ref prm, U, GradU, f); var f_tmp = f; f = f_check; f_check = f_tmp; } #endif for (int l = 0; l < L; l++) // loop over cells... { cpv.jCell = prm.j0 + l; for (int k = 0; k < K; k++) // loop over nodes... { for (int np = 0; np < _NOParams; np++) { cpv.Parameters[np] = prm.ParameterVars[np][l, k]; } for (int d = 0; d < D; d++) { cpv.Xglobal[d] = prm.Xglobal[l, k, d]; } for (int na = 0; na < _NOargs; na++) { if (U[na] != null) { _U[na] = U[na][l, k]; } if (GradU[na] != null) { for (int d = 0; d < D; d++) { _GradU[na, d] = GradU[na][l, k, d]; } } } f[l, k] += volForm.VolumeForm(ref cpv, _U, _GradU, _V, _GradV); } } #if DEBUG if (f_check != null) { double f_RelErr = f_check.L2Dist(f) / Math.Max(f.L2Norm(), 1); Debug.Assert(f_RelErr < 1e-14); } #endif }