示例#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
        protected override void CreateFields()
        {
            spec_basis = new SpecFemBasis((GridData)this.GridData, 4);
            var dg_basis = spec_basis.ContainingDGBasis;

            //var dg_basis = new Basis(this.GridData, 2);


            origin    = new SinglePhaseField(dg_basis, "Origin");
            specField = new SpecFemField(spec_basis);
            Result    = new SinglePhaseField(dg_basis, "Result");


            //this.GridData.Vertices.Coordinates.PlotCoordinateLabels("Coords_" + base.MPIRank + ".png");
        }
示例#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
        /// <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);
            }
        }
示例#6
0
 public ContinuityProjectionSpecFem(SpecFemBasis myBasis)
 {
     FEMLevSet = new SpecFemField(myBasis);
 }