Пример #1
0
        /// <summary>
        /// The orientation of the non-tranformed LumpedPort and the normal
        /// direction of its excitation vector should match.
        /// </summary>
        //[Fact(Skip="Disable output while developing other test cases")]
        public void LumpedPort_WithoutTransformation_NormalDirectionCorrect()
        {
            Compound   excitation = new Compound("Excitation");
            LumpedPort lumpedPort = new LumpedPort(0, 1, 50, new Vector3D(), new Vector3D(1, 1, 1), ENormDir.X);

            excitation.Add(lumpedPort);
            Assert.True(false, "Test not implemented yet");
        }
Пример #2
0
        static void ExportAntenna_Small_15x6mm()
        {
            double thickness       = 0.01;
            double airBox          = 5.0;
            double innerResolution = 0.5;
            double outerResolution = 5.0;

            var antenna = new CSXCAD.Antenna.Small_15x6mm_2400MHz(thickness);

            const double pcbThickness = 1.5;
            var          lumpedPort   = new LumpedPort(90, 1, 50, new Vector3D(0.0, 0.0, -pcbThickness), new Vector3D(0.0, 0.0, 0), ENormDir.Z, true);

            antenna.Add(lumpedPort);

            double margin      = 2.0;
            double groundWidth = 5.0;
            var    p1          = new Vector3D(antenna.BoundingBox.P1.x - margin, -groundWidth - margin, -pcbThickness);
            var    p2          = new Vector3D(antenna.BoundingBox.P2.x + margin, antenna.BoundingBox.P2.y + margin, 0);

            double epsRel    = 4.88;
            var    substrate = new Dielectric("pcb", epsRel, 1e-3 * 2 * Math.PI * 2.45e9 * epsRel * Material.Eps0);

            substrate.EdgeColor = new Material.Color(10, 255, 10, 128);
            substrate.FillColor = new Material.Color(10, 255, 10, 128);
            var pcb = new CSXCAD.Box(null, substrate, 60, p1, p2);

            antenna.Add(pcb);

            var bottomGround = new Metal("bottom-ground");

            bottomGround.EdgeColor = new Material.Color(235, 148, 7, 255);
            bottomGround.FillColor = bottomGround.EdgeColor;
            var bottomGroundPlane = new CSXCAD.Box(null, bottomGround, 100,
                                                   new Vector3D(antenna.BoundingBox.P1.x - antenna.D1, antenna.D4 / 2, -pcbThickness),
                                                   new Vector3D(antenna.BoundingBox.P2.x + antenna.D3, -groundWidth, -pcbThickness - 0.01));

            antenna.Add(bottomGroundPlane);

            var topGround = new Metal("top-ground");

            topGround.EdgeColor = new Material.Color(235, 148, 7, 255);
            topGround.FillColor = topGround.EdgeColor;
            var topGroundPlane = new CSXCAD.Box(null, topGround, 100,
                                                new Vector3D(antenna.BoundingBox.P1.x - antenna.D1, -antenna.D4 / 2, 0),
                                                new Vector3D(antenna.BoundingBox.P2.x + antenna.D3, -groundWidth, 0.01));

            antenna.Add(topGroundPlane);

            var viaMetal = new Metal("via");

            viaMetal.EdgeColor = new Material.Color(235, 148, 7, 255);
            viaMetal.FillColor = viaMetal.EdgeColor;
            var via = new Cylinder(null, viaMetal, 100,
                                   new Vector3D(-(antenna.W1 / 2 + antenna.D5 + antenna.W2 / 2), 0, -pcbThickness),
                                   new Vector3D(-(antenna.W1 / 2 + antenna.D5 + antenna.W2 / 2), 0, 0),
                                   0.25);

            antenna.Add(via);

            Simulation fdtd = new Simulation();

            fdtd.Excitation = new GaussExcitation(2450e6, 500e6);

            RectilinearGrid grid = new RectilinearGrid();;

            grid.Add(new Vector3D(0, 0, 0));
            grid.Add(pcb.P1);
            grid.Add(pcb.P2);

            /*
             * foreach (var v in antenna.antennaPoly)
             * {
             *  grid.Add(new Vector3D(v.x, v.y, 0));
             * }
             */

            grid.SmoothMesh(innerResolution);
            grid.AddAirbox(airBox);
            grid.SmoothMesh(outerResolution);
            var nf2ff = new NF2FFBox("nf2ff",
                                     new Vector3D(grid.XLines.First(), grid.YLines.First(), grid.ZLines.First()),
                                     new Vector3D(grid.XLines.Last(), grid.YLines.Last(), grid.ZLines.Last()));

            antenna.Add(nf2ff);
            grid.AddPML(8);

            XDocument doc = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                new XComment("Test XML file for CyPhy generated openEMS simulations"),
                new XElement("openEMS",
                             fdtd.ToXElement(),
                             new XElement("ContinuousStructure",
                                          new XAttribute("CoordSystem", 0),
                                          antenna.ToXElement(),
                                          grid.ToXElement()
                                          )
                             )
                );

            doc.Save("Small_15x6mm.xml");
        }
Пример #3
0
        static void ExportAntenna_InvertedF()
        {
            double thickness       = 0.01;
            double airBox          = 5.0;
            double innerResolution = 0.5;
            double outerResolution = 5.0;

            var antenna = new CSXCAD.Antenna.InvertedF_2400MHz(thickness);

            const double pcbThickness = 1.5;
            var          lumpedPort   = new LumpedPort(90, 1, 50, new Vector3D(0.0, 0.0, -pcbThickness), new Vector3D(0.0, 0.0, 0), ENormDir.Z, true);

            antenna.Add(lumpedPort);

            double margin      = 2.0;
            double groundWidth = 5.0;
            var    p1          = new Vector3D(antenna.BoundingBox.P1.x - margin, -groundWidth - margin, -pcbThickness);
            var    p2          = new Vector3D(antenna.BoundingBox.P2.x + margin, antenna.BoundingBox.P2.y + margin, 0);

            var substrate = new Dielectric("pcb", 3.38, 1e-3 * 2 * Math.PI * 2.45e9 * 3.38 * Material.Eps0);

            substrate.EdgeColor = new Material.Color(10, 255, 10, 128);
            substrate.FillColor = new Material.Color(10, 255, 10, 128);
            var pcb = new CSXCAD.Box(null, substrate, 60, p1, p2);
            //antenna.Add(pcb);

            var topGround = new Metal("bottom-ground");

            topGround.EdgeColor = new Material.Color(235, 148, 7, 255);
            topGround.FillColor = topGround.EdgeColor;
            var topGroundPlane = new CSXCAD.Box(null, topGround, 100,
                                                new Vector3D(antenna.BoundingBox.P1.x, 0, -pcbThickness),
                                                new Vector3D(antenna.BoundingBox.P2.x, -groundWidth, -pcbThickness));

            antenna.Add(topGroundPlane);

            var bottomGround = new Metal("top-ground");

            bottomGround.EdgeColor = new Material.Color(235, 148, 7, 255);
            bottomGround.FillColor = bottomGround.EdgeColor;
            var topGroundPlaneLeft = new CSXCAD.Box(null, bottomGround, 100,
                                                    new Vector3D(antenna.BoundingBox.P1.x, 0, 0),
                                                    new Vector3D(-0.46 / 2 - 0.45, -groundWidth, 0));
            var topGroundPlaneRight = new CSXCAD.Box(null, bottomGround, 100,
                                                     new Vector3D(0.46 / 2 + 0.45, 0, 0),
                                                     new Vector3D(antenna.BoundingBox.P2.x, -groundWidth, 0));

            antenna.Add(topGroundPlaneLeft);
            antenna.Add(topGroundPlaneRight);

            Simulation fdtd = new Simulation();

            fdtd.Excitation = new GaussExcitation(2450e6, 500e6);

            RectilinearGrid grid = new RectilinearGrid();;

            grid.Add(new Vector3D(0, 0, 0));

            grid.SmoothMesh(innerResolution);
            grid.AddAirbox(airBox);
            grid.SmoothMesh(outerResolution);
            var nf2ff = new NF2FFBox("nf2ff",
                                     new Vector3D(grid.XLines.First(), grid.YLines.First(), grid.ZLines.First()),
                                     new Vector3D(grid.XLines.Last(), grid.YLines.Last(), grid.ZLines.Last()));

            antenna.Add(nf2ff);
            grid.AddPML(8);

            XDocument doc = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                new XComment("Test XML file for CyPhy generated openEMS simulations"),
                new XElement("openEMS",
                             fdtd.ToXElement(),
                             new XElement("ContinuousStructure",
                                          new XAttribute("CoordSystem", 0),
                                          antenna.ToXElement(),
                                          grid.ToXElement()
                                          )
                             )
                );

            doc.Save("InvertedF.xml");
        }
Пример #4
0
        static void ProcessSAR(string inputFileName)
        {
            // Constants
            XElement xDoc    = XElement.Load(inputFileName);
            double   f0      = Convert.ToDouble(xDoc.Element("FDTD").Element("Excitation").Attribute("f0").Value);
            var      leQuery = from xe in xDoc.Element("ContinuousStructure").Element("Properties").Elements("LumpedElement")
                               where xe.Attribute("Name").Value.Contains("resist")
                               select xe;
            double r = Convert.ToDouble(leQuery.First().Attribute("R").Value);

            // Port calculations
            double[] freqs      = Utility.LinearSpace(f0 / 2, f0 * 3 / 2, 501);
            var      lumpedPort = new LumpedPort(0, 1, r, new Vector3D(-10, -1, -1), new Vector3D(10, 1, 1), ENormDir.X, true);

            lumpedPort.ReadResults(freqs);
            double Pin_f0 = lumpedPort.GetPFdInAt(f0);

            Console.WriteLine();

            // SAR
            string sarFileName = @"SAR.h5";
            var    sarDump     = new Postprocess.SAR(sarFileName);
            double totalPower  = HDF5.ReadAttribute(sarFileName, @"/FieldData/FD/f0", "power");

            Console.WriteLine("Field maximum: {0:e4}", sarDump.MaxValue);
            Console.WriteLine("Field maximum location: ({0})", String.Join(",", sarDump.MaxCoordinates.Select(x => String.Format("{0:f2}", x))));

            Console.WriteLine("Exporting SAR dump slices to PNG files...");
            string filenameSarX = "SAR-X.png";
            string filenameSarY = "SAR-Y.png";
            string filenameSarZ = "SAR-Z.png";

            sarDump.ToPNG(filenameSarX, Postprocess.SAR.ENormDir.X, sarDump.MaxCoordinates[0]);
            sarDump.ToPNG(filenameSarY, Postprocess.SAR.ENormDir.Y, sarDump.MaxCoordinates[1]);
            sarDump.ToPNG(filenameSarZ, Postprocess.SAR.ENormDir.Z, sarDump.MaxCoordinates[2]);
            Console.WriteLine("Exporting SAR to VTK file...");
            sarDump.ToVTK(inputFileName);

            // NF2FF
            Console.WriteLine("Calculating antenna parameters...");
            var nf2ff = new Postprocess.NF2FF(f0);

            try
            {
                nf2ff.ReadHDF5Result();

                Console.WriteLine("Maximum SAR:    {0:f3} W/kg (normalized to 1 W accepted power)", sarDump.MaxValue / Pin_f0);
                Console.WriteLine("Accepted power: {0:e4} W", Pin_f0);
                Console.WriteLine("Radiated power: {0:e4} W", nf2ff.RadiatedPower);
                Console.WriteLine("Absorbed power: {0:e4} W", totalPower);
                Console.WriteLine("Power budget:   {0:f3} %", 100 * (nf2ff.RadiatedPower + totalPower) / Pin_f0);

                Console.WriteLine("Populating manifest file...");
                var manifest = AVM.DDP.MetaTBManifest.OpenForUpdate(manifestPath);

                // Initialize Metrics list if necessary
                if (manifest.Metrics == null)
                {
                    manifest.Metrics = new List <AVM.DDP.MetaTBManifest.Metric>();
                }

                // Look for existing metric. Create a new one if not found.
                string metricName = "SAR_max";
                AVM.DDP.MetaTBManifest.Metric metric = manifest.Metrics.FirstOrDefault(m => m.Name.Equals(metricName));
                if (metric == null)
                {
                    metric = new AVM.DDP.MetaTBManifest.Metric()
                    {
                        Name = metricName
                    };
                    manifest.Metrics.Add(metric);
                }

                // Set metric attributes
                metric.DisplayedName = "SAR maximum";
                metric.Description   = "Maximum Specific Absorption Ratio (SAR) averaged over volumes containing 1 gram of tissue.";
                metric.Unit          = "W/kg";
                metric.Value         = String.Format("{0:e4}", sarDump.MaxValue / Pin_f0);

                metric.VisualizationArtifacts = new List <AVM.DDP.MetaTBManifest.Artifact>();
                metric.VisualizationArtifacts.Add(new AVM.DDP.MetaTBManifest.Artifact()
                {
                    Location = filenameSarX, Tag = "CyPhy2RF::SAR::X"
                });
                metric.VisualizationArtifacts.Add(new AVM.DDP.MetaTBManifest.Artifact()
                {
                    Location = filenameSarY, Tag = "CyPhy2RF::SAR::Y"
                });
                metric.VisualizationArtifacts.Add(new AVM.DDP.MetaTBManifest.Artifact()
                {
                    Location = filenameSarZ, Tag = "CyPhy2RF::SAR::Z"
                });

                manifest.Serialize(manifestPath);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error reading far-field results: {0}", e);
            }
        }
Пример #5
0
        static int ProcessNF2FF(string inputFileName)
        {
            // Constants
            XElement xDoc    = XElement.Load(inputFileName);
            double   f0      = Convert.ToDouble(xDoc.Element("FDTD").Element("Excitation").Attribute("f0").Value);
            var      leQuery = from xe in xDoc.Element("ContinuousStructure").Element("Properties").Elements("LumpedElement")
                               where xe.Attribute("Name").Value.Contains("resist")
                               select xe;
            double r = Convert.ToDouble(leQuery.First().Attribute("R").Value);

            // Port calculations
            double[] freqs       = Utility.LinearSpace(f0 / 2, f0 * 3 / 2, 501);
            var      antennaPort = new LumpedPort(0, 1, r, new Vector3D(-10, -1, -1), new Vector3D(10, 1, 1), ENormDir.X, true);

            antennaPort.ReadResults(freqs);
            double Pin_f0 = antennaPort.GetPFdInAt(f0);

            // NF2FF
            var nf2ff = new Postprocess.NF2FF(f0);

            try
            {
                nf2ff.ReadHDF5Result();
                nf2ff.ToVTK(fileName: "directivity_pattern.vtk");

                Console.WriteLine("Radiated power:    {0,15:e4} W", nf2ff.RadiatedPower);
                Console.WriteLine("Directivity (max): {0,15:e4} dBi", 10.0 * Math.Log10(nf2ff.Directivity));

                var manifest = AVM.DDP.MetaTBManifest.OpenForUpdate(manifestPath);

                // Initialize Metrics list if necessary
                if (manifest.Metrics == null)
                {
                    manifest.Metrics = new List <AVM.DDP.MetaTBManifest.Metric>();
                }

                // Look for existing metric. Create a new one if not found.
                string metricName = "Directivity";
                AVM.DDP.MetaTBManifest.Metric metric = manifest.Metrics.FirstOrDefault(m => m.Name.Equals(metricName));
                if (metric == null)
                {
                    metric = new AVM.DDP.MetaTBManifest.Metric()
                    {
                        Name = metricName
                    };
                    manifest.Metrics.Add(metric);
                }

                // Set metric attributes
                metric.DisplayedName = "Antenna directivity";
                metric.Description   = "Antenna directivity.";
                metric.Unit          = "dBi";
                metric.Value         = String.Format("{0:e4}", 10.0 * Math.Log10(nf2ff.Directivity));

                manifest.Serialize(manifestPath);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error reading far-field results: {0}", e);
                return(5);
            }
            return(0);
        }
Пример #6
0
        private XDocument BuildDipoleSarXml()
        {
            double unit = 1e-3;

            double f0      = 1e9;
            double c0      = 299792458.0;
            double lambda0 = c0 / f0;

            double fStop     = 1.5e9;
            double lambdaMin = c0 / fStop;

            // Simulation engine
            Simulation fdtd = new Simulation();

            fdtd.Excitation = new GaussExcitation(0, fStop); // possible typo in Dipole_SAR.xml

            // Simulation space
            Compound s = new Compound("space");

            // Dipole antenna
            double dipoleLength = 0.46 * lambda0 / unit;

            s.Add(new Box(null, new Metal("Dipole"), 1,
                          new Vector3D(0, 0, -dipoleLength / 2), new Vector3D(0, 0, dipoleLength / 2)));

            // Phantom
            Compound headPhantom = new Compound("head-phantom");

            Dielectric skinMaterial = new Dielectric("skin", 50, kappa: 0.65, density: 1100);

            skinMaterial.FillColor = new Material.Color(245, 215, 205, 250);
            skinMaterial.EdgeColor = new Material.Color(255, 235, 217, 250);
            Sphere skin = new Sphere(null, skinMaterial, 11, new Vector3D(), 1);

            skin.Transformations.Add(new TScale(80, 100, 100));
            headPhantom.Add(skin);

            Dielectric boneMaterial = new Dielectric("headbone", 13, kappa: 0.1, density: 2000);

            boneMaterial.FillColor = new Material.Color(227, 227, 227, 250);
            boneMaterial.EdgeColor = new Material.Color(202, 202, 202, 250);
            Sphere bone = new Sphere(null, boneMaterial, 12, new Vector3D(), 1);

            bone.Transformations.Add(new TScale(75, 95, 95));
            headPhantom.Add(bone);

            Dielectric brainMaterial = new Dielectric("brain", 60, kappa: 0.7, density: 1040);

            brainMaterial.FillColor = new Material.Color(255, 85, 127, 250);
            brainMaterial.EdgeColor = new Material.Color(71, 222, 179, 250);
            Sphere brain = new Sphere(null, brainMaterial, 13, new Vector3D(), 1);

            brain.Transformations.Add(new TScale(65, 85, 85));
            headPhantom.Add(brain);

            headPhantom.Transformations.Add(new TTranslate(100, 0, 0));

            s.Add(headPhantom);

            // Excitation
            double meshResAir     = lambdaMin / 20 / unit;
            double meshResPhantom = 2.5;

            LumpedPort lp = new LumpedPort(100, 1, 50.0,
                                           new Vector3D(-0.1, -0.1, -meshResPhantom / 2),
                                           new Vector3D(+0.1, +0.1, +meshResPhantom / 2), ENormDir.Z, true);

            s.Add(lp);

            // Grid
            RectilinearGrid g = new RectilinearGrid();

            g.XLines.Add(0);
            g.YLines.Add(0);
            foreach (double z in new double[] { -1.0 / 3, 2.0 / 3 })
            {
                g.ZLines.Add(-dipoleLength / 2 - meshResPhantom * z);
                g.ZLines.Add(+dipoleLength / 2 + meshResPhantom * z);
            }

            foreach (Sphere sp in new Sphere[] { skin, bone, brain })
            {
                g.XLines.Add(sp.AbsoluteTransformation.Matrix[0, 3] + sp.AbsoluteTransformation.Matrix[0, 0]);
                g.XLines.Add(sp.AbsoluteTransformation.Matrix[0, 3] - sp.AbsoluteTransformation.Matrix[0, 0]);
                g.YLines.Add(sp.AbsoluteTransformation.Matrix[1, 3] + sp.AbsoluteTransformation.Matrix[1, 1]);
                g.YLines.Add(sp.AbsoluteTransformation.Matrix[1, 3] - sp.AbsoluteTransformation.Matrix[1, 1]);
                g.ZLines.Add(sp.AbsoluteTransformation.Matrix[2, 3] + sp.AbsoluteTransformation.Matrix[2, 2]);
                g.ZLines.Add(sp.AbsoluteTransformation.Matrix[2, 3] - sp.AbsoluteTransformation.Matrix[2, 2]);
            }

            g.ZLines.Add(-meshResPhantom / 2); // port
            g.ZLines.Add(+meshResPhantom / 2);

            // Mesh over dipole and phantom
            g.SmoothMesh(meshResPhantom);

            g.XLines.Add(-200);
            g.XLines.Add(250 + 100);
            g.YLines.Add(-250);
            g.YLines.Add(+250);
            g.ZLines.Add(-250);
            g.ZLines.Add(+250);

            g.SmoothMesh(meshResAir, 1.2);

            s.Add(new SARBox("SAR", f0, new Vector3D(-10, -100, -100), new Vector3D(180, 100, 100)));
            s.Add(new NF2FFBox("nf2ff",
                               new Vector3D(g.XLines.First(), g.YLines.First(), g.ZLines.First()),
                               new Vector3D(g.XLines.Last(), g.YLines.Last(), g.ZLines.Last()),
                               lambdaMin / 15 / unit));

            g.AddPML(10);

            g.XLines.Sort();
            g.YLines.Sort();
            g.ZLines.Sort();

            // Export
            return(new XDocument(
                       new XDeclaration("1.0", "utf-8", "yes"),
                       new XComment("Test XML file for CyPhy generated openEMS simulations"),
                       new XElement("openEMS",
                                    fdtd.ToXElement(),
                                    new XElement("ContinuousStructure",
                                                 new XAttribute("CoordSystem", 0),
                                                 s.ToXElement(),
                                                 g.ToXElement()
                                                 )
                                    )
                       ));
        }