예제 #1
0
        private SinglePhaseField SpecFEMInterpolation(string fieldName, SpecFemBasis basis, MultidimensionalArray rho, MultidimensionalArray u, MultidimensionalArray v, MultidimensionalArray p, Func <double, double, double, double, double> func)
        {
            SpecFemField specFEMField     = new SpecFemField(basis);
            int          noOfNodesPerCell = noOfNodesPerEdge * noOfNodesPerEdge;

            int[,] cellNodeToNode = specFEMField.Basis.CellNode_To_Node;

            Debug.Assert(cellNodeToNode.GetLength(1) == noOfNodesPerCell);
            for (int i = 0; i < gridData.Grid.NoOfUpdateCells; i++)
            {
                for (int j = 0; j < noOfNodesPerCell; j++)
                {
                    int matlabNodeIndex = GetLocalMatlabNodeIndex(
                        basis.CellNodes[0][j, 0], basis.CellNodes[0][j, 1]);

                    var indices = GetNodeIndices(i, matlabNodeIndex);
                    specFEMField.Coordinates[cellNodeToNode[i, j]] = func(
                        rho[indices.Item1, indices.Item2],
                        u[indices.Item1, indices.Item2],
                        v[indices.Item1, indices.Item2],
                        p[indices.Item1, indices.Item2]);
                }
            }

            SinglePhaseField dgField = new SinglePhaseField(new Basis(gridData, dgDegree), fieldName);

            specFEMField.AccToDGField(1.0, dgField);
            return(dgField);
        }
예제 #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="gridData"></param>
        /// <param name="config"></param>
        public IBMFieldSet(IGridData gridData, IBMControl config)
            : base(gridData, config)
        {
            this.config = config;

            if (config.RestartInfo == null && !config.FieldOptions.ContainsKey(IBMVariables.LevelSet))
            {
                throw new Exception(
                          "Field 'levelSet' is required for IBM applications");
            }

            LevelSet = new LevelSet(
                new Basis(gridData, config.FieldOptions[IBMVariables.LevelSet].Degree),
                IBMVariables.LevelSet);

            if (config.ContinuousLevelSet)
            {
                SpecFemBasis specFEMBasis = new SpecFemBasis((GridData)gridData, LevelSet.Basis.Degree);

                SpecFemField specFemField = new SpecFemField(specFEMBasis);
                specFemField.ProjectDGFieldMaximum(1.0, LevelSet);
                LevelSet.Clear();
                specFemField.AccToDGField(1.0, LevelSet);
            }

            LevelSetGradient = new DGField[CompressibleEnvironment.NumberOfDimensions];
            for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
            {
                LevelSetGradient[d] = DerivedFields[IBMVariables.LevelSetGradient[d]];
            }
        }
예제 #3
0
 public void MakeContinuous(SinglePhaseField DGLevelSet, SinglePhaseField LevelSet, CellMask Domain)
 {
     FEMLevSet.ProjectDGField(1.0, DGLevelSet, Domain);
     LevelSet.Clear();
     FEMLevSet.AccToDGField(1.0, LevelSet, Domain);
     LevelSet.AccLaidBack(1.0, DGLevelSet, Domain.Complement());
 }
예제 #4
0
        private void UpdateArtificialViscosity()
        {
            // Determine piecewise constant viscosity
            this.ArtificialViscosityField.Clear();

            // Cell masks
            CellMask cutCells        = this.LevelSetTracker.Regions.GetCutCellMask();
            CellMask speciesA_nonCut = this.LevelSetTracker.Regions.GetSpeciesMask("A").Except(cutCells);
            CellMask speciesB_nonCut = this.LevelSetTracker.Regions.GetSpeciesMask("B").Except(cutCells);

            // Calculate AV
            SetAVForSpecies(speciesA_nonCut, "A");
            SetAVForSpecies(speciesB_nonCut, "B");
            SetAVForCutCells(cutCells);

            // Set AV manually for testing
            //this.ArtificialViscosityField.Clear();
            //this.ArtificialViscosityField.AccConstant(1.0);

            // Project visocsity onto continuous, multilinear space
            if (CompressibleEnvironment.NumberOfDimensions < 3)
            {
                // Standard version
                if (avSpecFEMBasis == null || !this.ArtificialViscosityField.Basis.Equals(avSpecFEMBasis.ContainingDGBasis))
                {
                    avSpecFEMBasis = new SpecFemBasis((GridData)this.GridData, 2);
                }
                SpecFemField specFemField = new SpecFemField(avSpecFEMBasis);
                specFemField.ProjectDGFieldMaximum(1.0, this.ArtificialViscosityField);
                this.ArtificialViscosityField.Clear();
                specFemField.AccToDGField(1.0, this.ArtificialViscosityField);
            }
            else
            {
                throw new NotImplementedException("Artificial viscosity has only been tested for 2D");
            }
        }
예제 #5
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            //origin.ProjectField((x, y) => 1-x*x);
            origin.ProjectField((x, y) => x * x + y * y * y - x * y);

            specField.ProjectDGFieldCheaply(1.0, origin);
            //specField.ProjectDGField(1.0, origin);

            /*
             * if (this.MPIRank >= 0) {
             *  // specField.Coordinates[46] = 1;
             *  // specField.Coordinates[48] = -1;
             *  ilPSP.Environment.StdoutOnlyOnRank0 = false;
             *
             *  Random R = new Random();
             *
             *  for (int t = 1; t <= 2; t++) {
             *      int i0 = spec_basis.GetLocalOwnedNodesOffset(t);
             *      int L = spec_basis.GetNoOfOwnedNodes(t);
             *
             *
             *      for (int l = 0; l < L; l++) {
             *          double x = specField.Basis.GlobalNodes[i0 + l, 0];
             *          double y = specField.Basis.GlobalNodes[i0 + l, 1];
             *
             *          specField.Coordinates[i0 + l] = R.NextDouble();
             *
             *          //if (Math.Abs(x - (+2.0)) < 1.0e-8) {
             *          //    Console.WriteLine("Hi! R" + this.MPIRank + ", " + (l + i0) + " (" + x + "," + y + ")");
             *          //    specField.Coordinates[i0 + l] = y;
             *          //}
             *
             *      }
             *  }
             *
             *  //ilPSP.Environment.StdoutOnlyOnRank0 = true;
             *
             * }*/


            using (var m_transciever = new Foundation.SpecFEM.Transceiver(spec_basis)) {
                m_transciever.Scatter(specField.Coordinates);
            }

            specField.AccToDGField(1.0, Result);

            var ERR = origin.CloneAs();

            ERR.Acc(-1.0, Result);

            double L2Err  = ERR.L2Norm();
            double L2Jump = JumpNorm(Result);

            Console.WriteLine("L2 Error: " + L2Err);
            Console.WriteLine("L2 Norm of [[u]]: " + L2Jump);
            if ((L2Err < 1.0e-10 || this.Grid.PeriodicTrafo.Count > 0) && L2Jump < 1.0e-10)
            {
                Console.WriteLine("Test PASSED");
                Passed = true;
            }
            else
            {
                Console.WriteLine("Test FAILED");
                Passed = false;
            }

            Passed = true;

            base.TerminationKey = true;
            return(0.0);
        }
예제 #6
0
        /// <summary>
        /// Deprecated utility, writes matrices for spectral element method.
        /// </summary>
        public void WriteSEMMatrices() {
            int kSEM; // nodes per edge

            if (this.Grid.RefElements[0] is Triangle) {
                kSEM = this.T.Basis.Degree + 1;
            } else if (this.Grid.RefElements[0] is Square) {
                switch (this.T.Basis.Degree) {
                    case 2: kSEM = 2; break;
                    case 3: kSEM = 2; break;
                    case 4: kSEM = 3; break;
                    case 5: kSEM = 3; break;
                    case 6: kSEM = 4; break;
                    default: throw new NotSupportedException();
                }
            } else {
                throw new NotImplementedException();
            }

            SpecFemBasis SEM_basis = new SpecFemBasis((GridData)(this.GridData), kSEM);

            SEM_basis.CellNodes[0].SaveToTextFile("NODES_SEM" + kSEM + ".txt");
            SEM_basis.MassMatrix.SaveToTextFileSparse("MASS_SEM" + kSEM + ".txt");

            var Mod2Nod = SEM_basis.GetModal2NodalOperator(this.T.Basis);
            var Nod2Mod = SEM_basis.GetNodal2ModalOperator(this.T.Basis);

            Mod2Nod.SaveToTextFileSparse("MODAL" + this.T.Basis.Degree + "_TO_NODAL" + kSEM + ".txt");
            Nod2Mod.SaveToTextFileSparse("NODAL" + kSEM + "_TO_MODAL" + this.T.Basis.Degree + ".txt");

            this.LaplaceMtx.SaveToTextFileSparse("OPERATOR" + this.T.Basis.Degree + ".txt");


            {
                var TEST = this.T.CloneAs();
                TEST.Clear();
                TEST.ProjectField((_2D)((x, y) => x * y));

                int J = this.GridData.iGeomCells.Count;
                int N = SEM_basis.NodesPerCell[0];
                MultidimensionalArray TEST_at_NODES = MultidimensionalArray.Create(J, N);

                TEST.Evaluate(0, J, SEM_basis.CellNodes[0], TEST_at_NODES);

                double[] CompareAtNodes = new double[J * N];
                Mod2Nod.SpMVpara(1.0, TEST.CoordinateVector, 0.0, CompareAtNodes);

                double[] gretchen = TEST_at_NODES.ResizeShallow(J * N).To1DArray();

                double fdist = GenericBlas.L2Dist(gretchen, CompareAtNodes);
                Debug.Assert(fdist < 1.0e-8);

                double[] bak = new double[TEST.Mapping.LocalLength];
                Nod2Mod.SpMVpara(1.0, CompareAtNodes, 0.0, bak);

                double hdist = GenericBlas.L2Dist(bak, TEST.CoordinateVector);
                Debug.Assert(hdist < 1.0e-8);
            }


            var Scatter = SEM_basis.GetNodeScatterMatrix();

            Scatter.SaveToTextFileSparse("SCATTER_SEM" + kSEM + ".txt");


            {
                var SEMTEST = new SpecFemField(SEM_basis);
                var csem = SEMTEST.Coordinates;

                Random r = new Random(666);
                for (int i = 0; i < csem.GetLength(0); i++) {
                    csem[i] = r.NextDouble();
                }


                var DG_TEST0 = new SinglePhaseField(SEMTEST.Basis.ContainingDGBasis);
                var DG_TEST = this.T.CloneAs();
                DG_TEST.Clear();
                SEMTEST.AccToDGField(1.0, DG_TEST0);
                DG_TEST.AccLaidBack(1.0, DG_TEST0);

                double[] S2 = new double[Scatter.RowPartitioning.LocalLength];
                double[] S3 = new double[DG_TEST.Mapping.LocalLength];

                Scatter.SpMVpara(1.0, csem.To1DArray(), 0.0, S2);
                Nod2Mod.SpMVpara(1.0, S2, 0.0, S3);

                double gdist = GenericBlas.L2Dist(S3, DG_TEST.CoordinateVector);
                Debug.Assert(gdist < 1.0e-8);
            }
        }