public static void TestIterativeSolver( #if DEBUG [Values(2)] int dgDeg, [Values(40)] int res, [Values(2)] int dim, [Values(SolverCodes.exp_softpcg_schwarz)] SolverCodes solver
/// <summary> /// Test on a Cartesian grid, with a sinusodial solution. /// </summary> /// <param name="Res"> /// Grid resolution /// </param> /// <param name="Dim"> /// spatial dimension /// </param> /// <param name="deg"> /// polynomial degree /// </param> /// <param name="solver_name"> /// Name of solver to use. /// </param> public static SipControl TestCartesian2(int Res, int Dim, SolverCodes solver_name = SolverCodes.exp_softpcg_mg, int deg = 3) { if (Dim != 2 && Dim != 3) { throw new ArgumentOutOfRangeException(); } var R = new SipControl(); R.ProjectName = "ipPoison/cartesian"; R.savetodb = false; R.FieldOptions.Add("T", new FieldOpts() { Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); R.FieldOptions.Add("Tex", new FieldOpts() { Degree = deg * 2 }); R.InitialValues_Evaluators.Add("RHS", X => - Math.Sin(X[0])); R.InitialValues_Evaluators.Add("Tex", X => Math.Sin(X[0])); R.ExactSolution_provided = true; R.NoOfMultigridLevels = int.MaxValue; R.solver_name = solver_name; //R.TargetBlockSize = 100; R.TracingNamespaces = "BoSSS,ilPSP"; R.GridFunc = delegate() { GridCommons grd = null; if (Dim == 2) { double[] xNodes = GenericBlas.Linspace(0, 10, Res * 5 + 1); double[] yNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1); grd = Grid2D.Cartesian2DGrid(xNodes, yNodes); } else if (Dim == 3) { double[] xNodes = GenericBlas.Linspace(0, 10, Res * 5 + 1); double[] yNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1); double[] zNodes = GenericBlas.SinLinSpacing(-1, +1, 0.6, Res + 1); grd = Grid3D.Cartesian3DGrid(xNodes, yNodes, zNodes); } else { throw new NotSupportedException(); } grd.EdgeTagNames.Add(1, BoundaryType.Dirichlet.ToString()); grd.EdgeTagNames.Add(2, BoundaryType.Neumann.ToString()); grd.DefineEdgeTags(delegate(double[] X) { byte ret; if (Math.Abs(X[0] - 0.0) <= 1.0e-6) { ret = 1; } else { ret = 2; } return(ret); }); return(grd); }; R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T", delegate(double[] X) { double x = X[0], y = X[1]; if (Math.Abs(X[0] - (0.0)) < 1.0e-8) { return(0.0); } throw new ArgumentOutOfRangeException(); }); R.AddBoundaryValue(BoundaryType.Neumann.ToString(), "T", delegate(double[] X) { if (Math.Abs(X[1] - 1.0) < 1.0e-8 || Math.Abs(X[1] + 1.0) < 1.0e-8) // y = -1, y = +1 { return(0); } if (X.Length > 2 && (Math.Abs(X[2] - 1.0) < 1.0e-8 || Math.Abs(X[2] + 1.0) < 1.0e-8)) // z = -1, z = +1 { return(0); } if (Math.Abs(X[0] - (+10.0)) < 1.0e-8) { return(Math.Cos(10.0)); } throw new ArgumentOutOfRangeException(); }); return(R); }
/// <summary> /// Test on a 2D Voronoi mesh /// </summary> /// <param name="Res"> /// number of randomly chosen Delaunay vertices /// </param> /// <param name="deg"> /// polynomial degree /// </param> /// <param name="solver_name"> /// Name of solver to use. /// </param> public static SipControl TestVoronoi(int Res, SolverCodes solver_name = SolverCodes.classic_pardiso, int deg = 3) { if (System.Environment.MachineName.ToLowerInvariant().EndsWith("rennmaschin") //|| System.Environment.MachineName.ToLowerInvariant().Contains("jenkins") ) { // This is Florians Laptop; // he is to poor to afford MATLAB, so he uses OCTAVE BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave; BatchmodeConnector.MatlabExecuteable = "C:\\cygwin64\\bin\\bash.exe"; } var R = new SipControl(); R.ProjectName = "SipPoisson-Voronoi"; R.SessionName = "testrun"; R.savetodb = false; R.FieldOptions.Add("T", new FieldOpts() { Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); R.FieldOptions.Add("Tex", new FieldOpts() { Degree = deg * 2 }); R.InitialValues_Evaluators.Add("RHS", X => 1.0); R.InitialValues_Evaluators.Add("Tex", X => 0.0); R.ExactSolution_provided = false; R.NoOfMultigridLevels = int.MaxValue; R.solver_name = solver_name; //R.TargetBlockSize = 100; bool IsIn(params double[] X) { Debug.Assert(X.Length == 2); double xi = X[0]; double yi = X[1]; //for(int l = 0; l < bndys.Length; l++) { // Debug.Assert(bndys[l].Normal.Length == 2); // if (bndys[l].PointDistance(xi, yi) > 0.0) // return false; //} if (xi > 1.0) { return(false); } if (yi > 1.0) { return(false); } if (xi < 0 && yi < 0) { return(false); } if (xi < -1) { return(false); } if (yi < -1) { return(false); } return(true); } int Mirror(ref double[] _x, ref double[] _y, AffineManifold[] bndys) { if (_x.Length != _y.Length) { throw new ArgumentException(); } var x = _x.ToList(); var y = _y.ToList(); int N = _x.Length; // filter all points that are outside of the domain for (int n = 0; n < N; n++) { if (!IsIn(x[n], y[n])) { x.RemoveAt(n); y.RemoveAt(n); N--; n--; } } Debug.Assert(x.Count == N); Debug.Assert(y.Count == N); for (int n = 0; n < N; n++) { Debug.Assert(IsIn(x[n], y[n])); } // mirror each point for (int n = 0; n < N; n++) { double xn = x[n]; double yn = y[n]; for (int l = 0; l < bndys.Length; l++) { var bndy_l = bndys[l]; double dist = bndy_l.PointDistance(xn, yn); if (dist < 0) { double xMirr = xn - bndy_l.Normal[0] * dist * 2; double yMirr = yn - bndy_l.Normal[1] * dist * 2; Debug.Assert(bndy_l.PointDistance(xMirr, yMirr) > 0); if (!IsIn(xMirr, yMirr)) { x.Add(xMirr); y.Add(yMirr); } } } } // return _x = x.ToArray(); _y = y.ToArray(); return(N); } GridCommons GridFunc() { GridCommons grd = null; var Matlab = new BatchmodeConnector(); // boundaries for L-domain AffineManifold[] Boundaries = new AffineManifold[6]; Boundaries[0] = new AffineManifold(new[] { 0.0, 1.0 }, new[] { 0.0, 1.0 }); Boundaries[1] = new AffineManifold(new[] { 1.0, 0.0 }, new[] { 1.0, 0.0 }); Boundaries[2] = new AffineManifold(new[] { -1.0, 0.0 }, new[] { -1.0, 0.0 }); Boundaries[3] = new AffineManifold(new[] { -1.0, 0.0 }, new[] { 0.0, 0.0 }); Boundaries[4] = new AffineManifold(new[] { 0.0, -1.0 }, new[] { 0.0, -1.0 }); Boundaries[5] = new AffineManifold(new[] { 0.0, -1.0 }, new[] { 0.0, 0.0 }); // generate Delaunay vertices Random rnd = new Random(0); double[] xNodes = Res.ForLoop(idx => rnd.NextDouble() * 2 - 1); double[] yNodes = Res.ForLoop(idx => rnd.NextDouble() * 2 - 1); int ResFix = Mirror(ref xNodes, ref yNodes, Boundaries); var Nodes = MultidimensionalArray.Create(xNodes.Length, 2); Nodes.SetColumn(0, xNodes); Nodes.SetColumn(1, yNodes); Matlab.PutMatrix(Nodes, "Nodes"); // compute Voronoi diagramm Matlab.Cmd("[V, C] = voronoin(Nodes);"); // output (export from matlab) int[][] OutputVertexIndex = new int[Nodes.NoOfRows][]; Matlab.GetStaggeredIntArray(OutputVertexIndex, "C"); Matlab.GetMatrix(null, "V"); // run matlab Matlab.Execute(false); // import here MultidimensionalArray VertexCoordinates = (MultidimensionalArray)(Matlab.OutputObjects["V"]); // correct indices (1-based index to 0-based index) foreach (int[] cell in OutputVertexIndex) { int K = cell.Length; for (int k = 0; k < K; k++) { cell[k]--; } } // tessellation List <Cell> cells = new List <Cell>(); List <int[]> aggregation = new List <int[]>(); for (int jV = 0; jV < ResFix; jV++) // loop over Voronoi Cells { Debug.Assert(IsIn(Nodes.GetRow(jV))); int[] iVtxS = OutputVertexIndex[jV]; int NV = iVtxS.Length; List <int> Agg2Pt = new List <int>(); for (int iTri = 0; iTri < NV - 2; iTri++) // loop over triangles of voronoi cell { int iV0 = iVtxS[0]; int iV1 = iVtxS[iTri + 1]; int iV2 = iVtxS[iTri + 2]; double[] V0 = VertexCoordinates.GetRow(iV0); double[] V1 = VertexCoordinates.GetRow(iV1); double[] V2 = VertexCoordinates.GetRow(iV2); double[] D1 = V1.Minus(V0); double[] D2 = V2.Minus(V0); Debug.Assert(D1.CrossProduct2D(D2).Abs() > 1.0e-8); if (D1.CrossProduct2D(D2) < 0) { double[] T = V2; int t = iV2; V2 = V1; iV2 = iV1; V1 = T; iV1 = t; } double[] Center = V0.Plus(V1).Plus(V2).Mul(1.0 / 3.0); //Debug.Assert(IsIn(Center[0], Center[1])); Cell Cj = new Cell(); Cj.GlobalID = cells.Count; Cj.Type = CellType.Triangle_3; Cj.TransformationParams = MultidimensionalArray.Create(3, 2); Cj.NodeIndices = new int[] { iV0, iV1, iV2 }; Cj.TransformationParams.SetRow(0, V0); Cj.TransformationParams.SetRow(1, V1); Cj.TransformationParams.SetRow(2, V2); Agg2Pt.Add(cells.Count); cells.Add(Cj); } aggregation.Add(Agg2Pt.ToArray()); } // return grid grd = new Grid2D(Triangle.Instance); grd.Cells = cells.ToArray(); grd.EdgeTagNames.Add(1, BoundaryType.Dirichlet.ToString()); grd.DefineEdgeTags(X => (byte)1); //grd.Plot2DGrid(); // create aggregation grid //var agrd = new AggregationGrid(grd, aggregation.ToArray()); return(grd); }; R.GridFunc = GridFunc; R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T", delegate(double[] X) { //double x = X[0], y = X[1]; return(0.0); //if(Math.Abs(X[0] - (0.0)) < 1.0e-8) // return 0.0; // //throw new ArgumentOutOfRangeException(); }); return(R); }
/* * * /// <summary> * /// Test on a 2D Voronoi mesh * /// </summary> * /// <param name="Res"> * /// number of randomly chosen Delaunay vertices * /// </param> * /// <param name="deg"> * /// polynomial degree * /// </param> * /// <param name="solver_name"> * /// Name of solver to use. * /// </param> * public static SipControl TestVoronoiOld(int Res, SolverCodes solver_name = SolverCodes.classic_pardiso, int deg = 3) { * * if (System.Environment.MachineName.ToLowerInvariant().EndsWith("rennmaschin") * //|| System.Environment.MachineName.ToLowerInvariant().Contains("jenkins") * ) { * // This is Florians Laptop; * // he is to poor to afford MATLAB, so he uses OCTAVE * BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave; * BatchmodeConnector.MatlabExecuteable = "C:\\cygwin64\\bin\\bash.exe"; * } * * * var R = new SipControl(); * R.ProjectName = "SipPoisson-Voronoi"; * R.SessionName = "testrun"; * R.savetodb = false; * * R.FieldOptions.Add("T", new FieldOpts() { Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); * R.FieldOptions.Add("Tex", new FieldOpts() { Degree = deg*2 }); * R.InitialValues_Evaluators.Add("RHS", X => 1.0); * R.InitialValues_Evaluators.Add("Tex", X => 0.0); * R.ExactSolution_provided = false; * R.NoOfMultigridLevels = int.MaxValue; * R.solver_name = solver_name; * //R.TargetBlockSize = 100; * * * * * bool IsIn(double xi, double yi) { * * //for(int l = 0; l < bndys.Length; l++) { * // Debug.Assert(bndys[l].Normal.Length == 2); * // if (bndys[l].PointDistance(xi, yi) > 0.0) * // return false; * //} * if (xi > 1.0) * return false; * if (yi > 1.0) * return false; * if (xi < 0 && yi < 0) * return false; * if (xi < -1) * return false; * if (yi < -1) * return false; * * return true; * } * * bool IsInV(Vector X) { * Debug.Assert(X.Dim == 2); * return IsIn(X.x, X.y); * } * * int Mirror(ref double[] _x, ref double[] _y, AffineManifold[] bndys) { * if (_x.Length != _y.Length) * throw new ArgumentException(); * var x = _x.ToList(); * var y = _y.ToList(); * int N = _x.Length; * * * * // filter all points that are outside of the domain * for (int n = 0; n < N; n++) { * if (!IsIn(x[n], y[n])) { * x.RemoveAt(n); * y.RemoveAt(n); * N--; * n--; * } * } * Debug.Assert(x.Count == N); * Debug.Assert(y.Count == N); * for (int n = 0; n < N; n++) { * Debug.Assert(IsIn(x[n], y[n])); * } * * // mirror each point * for(int n = 0; n < N; n++) { * double xn = x[n]; * double yn = y[n]; * for(int l = 0; l < bndys.Length; l++) { * var bndy_l = bndys[l]; * * double dist = bndy_l.PointDistance(xn, yn); * * if(dist < 0) { * double xMirr = xn - bndy_l.Normal[0] * dist*2; * double yMirr = yn - bndy_l.Normal[1] * dist*2; * * Debug.Assert(bndy_l.PointDistance(xMirr, yMirr) > 0); * * if(!IsIn(xMirr, yMirr)) { * x.Add(xMirr); * y.Add(yMirr); * } * } * } * } * * // return * _x = x.ToArray(); * _y = y.ToArray(); * return N; * } * * * IGrid GridFunc() { * GridCommons grd = null; * * var Matlab = new BatchmodeConnector(); * * // boundaries for L-domain * AffineManifold[] Boundaries = new AffineManifold[6]; * Boundaries[0] = new AffineManifold(new[] { 0.0, 1.0 }, new[] { 0.0, 1.0 }); * Boundaries[1] = new AffineManifold(new[] { 1.0, 0.0 }, new[] { 1.0, 0.0 }); * Boundaries[2] = new AffineManifold(new[] { -1.0, 0.0 }, new[] { -1.0, 0.0 }); * Boundaries[3] = new AffineManifold(new[] { -1.0, 0.0 }, new[] { 0.0, 0.0 }); * Boundaries[4] = new AffineManifold(new[] { 0.0, -1.0 }, new[] { 0.0, -1.0 }); * Boundaries[5] = new AffineManifold(new[] { 0.0, -1.0 }, new[] { 0.0, 0.0 }); * * * // generate Delaunay vertices * Random rnd = new Random(0); * double[] xNodes = Res.ForLoop(idx => rnd.NextDouble()*2 - 1); * double[] yNodes = Res.ForLoop(idx => rnd.NextDouble()*2 - 1); * int ResFix = Mirror(ref xNodes, ref yNodes, Boundaries); * * * var Nodes = MultidimensionalArray.Create(xNodes.Length, 2); * Nodes.SetColumn(0, xNodes); * Nodes.SetColumn(1, yNodes); * * Matlab.PutMatrix(Nodes, "Nodes"); * * // compute Voronoi diagramm * Matlab.Cmd("[V, C] = voronoin(Nodes);"); * * // output (export from matlab) * int[][] OutputVertexIndex = new int[Nodes.NoOfRows][]; * Matlab.GetStaggeredIntArray(OutputVertexIndex, "C"); * Matlab.GetMatrix(null, "V"); * * // run matlab * Matlab.Execute(false); * * // import here * MultidimensionalArray VertexCoordinates = (MultidimensionalArray)(Matlab.OutputObjects["V"]); * * // correct indices (1-based index to 0-based index) * foreach(int[] cell in OutputVertexIndex) { * int K = cell.Length; * for (int k = 0; k < K; k++) { * cell[k]--; * } * } * * // tessellation * List<Cell> cells = new List<Cell>(); * List<int[]> aggregation = new List<int[]>(); * for(int jV = 0; jV < ResFix; jV++) { // loop over Voronoi Cells * Debug.Assert(IsInV(Nodes.GetRowPt(jV))); * * int[] iVtxS = OutputVertexIndex[jV]; * int NV = iVtxS.Length; * * List<int> Agg2Pt = new List<int>(); * * for(int iTri = 0; iTri < NV - 2; iTri++) { // loop over triangles of voronoi cell * int iV0 = iVtxS[0]; * int iV1 = iVtxS[iTri + 1]; * int iV2 = iVtxS[iTri + 2]; * * Vector V0 = VertexCoordinates.GetRowPt(iV0); * Vector V1 = VertexCoordinates.GetRowPt(iV1); * Vector V2 = VertexCoordinates.GetRowPt(iV2); * * double[] D1 = V1 - V0; * double[] D2 = V2 - V0; * Debug.Assert(D1.CrossProduct2D(D2).Abs() > 1.0e-8); * if(D1.CrossProduct2D(D2) < 0) { * Vector T = V2; * int t = iV2; * V2 = V1; * iV2 = iV1; * V1 = T; * iV1 = t; * } * * //double[] Center = V0.Plus(V1).Plus(V2).Mul(1.0 / 3.0); * //Debug.Assert(IsIn(Center[0], Center[1])); * * Cell Cj = new Cell(); * Cj.GlobalID = cells.Count; * Cj.Type = CellType.Triangle_3; * Cj.TransformationParams = MultidimensionalArray.Create(3, 2); * Cj.NodeIndices = new int[] { iV0, iV1, iV2 }; * Cj.TransformationParams.SetRowPt(0, V0); * Cj.TransformationParams.SetRowPt(1, V1); * Cj.TransformationParams.SetRowPt(2, V2); * * Agg2Pt.Add(cells.Count); * * cells.Add(Cj); * } * * aggregation.Add(Agg2Pt.ToArray()); * } * * // return grid * grd = new Grid2D(Triangle.Instance); * grd.Cells = cells.ToArray(); * grd.EdgeTagNames.Add(1, BoundaryType.Dirichlet.ToString()); * grd.DefineEdgeTags(X => (byte)1); * * //grd.Plot2DGrid(); * * // create aggregation grid * var agrd = new AggregationGrid(grd, aggregation.ToArray()); * return agrd; * * }; * R.GridFunc = GridFunc; * * R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T", * delegate (double[] X) { * //double x = X[0], y = X[1]; * * return 0.0; * //if(Math.Abs(X[0] - (0.0)) < 1.0e-8) * // return 0.0; * // * //throw new ArgumentOutOfRangeException(); * }); * * * * * * return R; * } * * //*/ /// <summary> /// Test on a 2D Voronoi mesh /// </summary> /// <param name="Res"> /// number of randomly chosen Delaunay vertices /// </param> /// <param name="deg"> /// polynomial degree /// </param> /// <param name="solver_name"> /// Name of solver to use. /// </param> /// <param name="mirror"> /// use vertex mirroring at boundary to make a large fraction of the Voronoi cells conformal /// </param> /// <param name="NoOfLlyodsIter"> /// Number of iterations for Llyod's algorithm (aka. Voronoi relaxation) /// </param> public static SipControl TestVoronoi(int Res, SolverCodes solver_name = SolverCodes.classic_pardiso, int deg = 1, bool mirror = true, double NoOfLlyodsIter = 0) { if (System.Environment.MachineName.ToLowerInvariant().EndsWith("rennmaschin") //|| System.Environment.MachineName.ToLowerInvariant().Contains("jenkins") ) { // This is Florians Laptop; // he is to poor to afford MATLAB, so he uses OCTAVE BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave; //BatchmodeConnector.MatlabExecuteable = "C:\\cygwin64\\bin\\bash.exe"; } var R = new SipControl(); R.ProjectName = "SipPoisson-Voronoi"; R.SessionName = "testrun"; R.savetodb = false; R.FieldOptions.Add("T", new FieldOpts() { Degree = deg, SaveToDB = FieldOpts.SaveToDBOpt.TRUE }); R.FieldOptions.Add("Tex", new FieldOpts() { Degree = deg * 2 }); R.InitialValues_Evaluators.Add("RHS", X => 0.0);// -1.0 + X[0] * X[0]); R.InitialValues_Evaluators.Add("Tex", X => X[0]); R.ExactSolution_provided = false; R.NoOfMultigridLevels = int.MaxValue; R.solver_name = solver_name; R.NoOfMultigridLevels = 1; //R.TargetBlockSize = 100; bool IsIn(double xi, double yi) { //for(int l = 0; l < bndys.Length; l++) { // Debug.Assert(bndys[l].Normal.Length == 2); // if (bndys[l].PointDistance(xi, yi) > 0.0) // return false; //} if (xi > 1.0) { return(false); } if (yi > 1.0) { return(false); } if (xi < 0 && yi < 0) { return(false); } if (xi < -1) { return(false); } if (yi < -1) { return(false); } return(true); } Vector[] DomainBndyPolygon = new[] { new Vector(+0, +0), new Vector(-1, +0), new Vector(-1, +1), new Vector(+1, +1), new Vector(+1, -1), new Vector(+0, -1) }; //*/ /* * bool IsIn(double xi, double yi) { * double myEps = 0.0; * if (xi > 1.0 + myEps) * return false; * if (yi > 1.0 + myEps) * return false; * if (xi < -1 - myEps) * return false; * if (yi < -1 - myEps) * return false; * * return true; * } * * * * Vector[] DomainBndyPolygon = new[] { * new Vector(-1,+1), * new Vector(+1,+1), * new Vector(+1,-1), * new Vector(-1,-1) * }; * //*/ bool IsInV(Vector X) { Debug.Assert(X.Dim == 2); return(IsIn(X.x, X.y)); } bool Idenity(Vector A, Vector B) { bool t2 = (A - B).AbsSquare() < 1.0e-10; bool t1 = (A - B).AbsSquare() < 1.0e-15; //Debug.Assert(t1 == t2); //Voronoi.VoronoiMeshGen.AccuracyFlag = (t1 == t2); return(t2); } IGrid GridFunc() { // generate Delaunay vertices Random rnd = new Random(0); int RR = Res; var Node = MultidimensionalArray.Create(RR, 2); bool useMirror = mirror; double scl = useMirror ? 2.0 : 4.0; int cmt = 0; while (cmt < Res) { double nx = rnd.NextDouble() * scl - 0.5 * scl; double ny = rnd.NextDouble() * scl - 0.5 * scl; if (IsIn(nx, ny)) { Node[cmt, 0] = nx; Node[cmt, 1] = ny; cmt++; } } // generate mesh return(Voronoi.VoronoiMeshGen.FromPolygonalDomain(Node, DomainBndyPolygon, useMirror, NoOfLlyodsIter, IsInV, Idenity)); }; R.GridFunc = GridFunc; R.AddBoundaryValue(BoundaryType.Dirichlet.ToString(), "T", delegate(double[] X) { //double x = X[0], y = X[1]; return(X[0]); //if(Math.Abs(X[0] - (0.0)) < 1.0e-8) // return 0.0; // //throw new ArgumentOutOfRangeException(); }); return(R); }