public void Grid() { double maxRes = 1.0; double maxRatio = 1.5; List <double> mesh; List <double> smoothMesh; List <string> referenceMesh; // #1 mesh = new List <double> { 0, 3 }; smoothMesh = RectilinearGrid.SmoothLines(mesh, maxRes, maxRatio); referenceMesh = new List <string> { "0.00", "1.00", "2.00", "3.00" }; //Console.Write("Original mesh: "); //Console.WriteLine(String.Join(", ", mesh.Select(i => String.Format("{0:f2}", i)).ToArray())); Assert.True(CompareGrid(referenceMesh, smoothMesh)); Console.WriteLine(); // #2 mesh = new List <double> { 0, 0.01, 3 }; smoothMesh = RectilinearGrid.SmoothLines(mesh, maxRes, maxRatio); referenceMesh = new List <string> { "0.00", "0.01", "0.03", "0.05", "0.08", "0.13", "0.21", "0.32", "0.49", "0.75", "1.13", "1.71", "2.35", "3.00" }; //Console.Write("Original mesh: "); //Console.WriteLine(String.Join(", ", mesh.Select(i => String.Format("{0:f2}", i)).ToArray())); Assert.True(CompareGrid(referenceMesh, smoothMesh)); /* * Console.WriteLine(); * * mesh = new List<double> { 0, 0.01, 2.99, 3 }; * smoothMesh = RectilinearGrid.SmoothLines(mesh, maxRes, maxRatio); * referenceMesh = new List<string> { * "0.00", "0.01", "0.03", "0.05", "0.08", "0.13", "0.21", "0.32", * "0.49", "0.75", "0.94", "1.12", "1.31", "1.87", "2.25", "2.51", * "2.68", "2.79", "2.87", "2.92", "2.95", "2.98", "2.99", "3.00" }; * * Console.WriteLine("maxRes = {0} ratio = {1}", maxRes, maxRatio); * Console.WriteLine("Original mesh:"); * Console.WriteLine(String.Join(", ", mesh.Select(i => String.Format("{0:f2}", i)).ToArray())); * * Assert.True(CompareGrid(referenceMesh, smoothMesh)); */ }
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"); }
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"); }
static void TestGrid() { double maxRes; double ratio; List <double> mesh; List <double> smoothMesh; List <string> referenceMesh; // #1 maxRes = 1; ratio = 1.5; mesh = new List <double> { 0, 3 }; smoothMesh = RectilinearGrid.SmoothLines(mesh, maxRes, ratio); referenceMesh = new List <string> { "0.00", "1.00", "2.00", "3.00" }; Console.WriteLine("maxRes = {0} ratio = {1}", maxRes, ratio); Console.WriteLine("Original mesh:"); Console.WriteLine(String.Join(", ", mesh.Select(i => String.Format("{0:f2}", i)).ToArray())); EvalGridTest(smoothMesh, referenceMesh); Console.WriteLine(); // #2 mesh = new List <double> { 0, 0.01, 3 }; smoothMesh = RectilinearGrid.SmoothLines(mesh, maxRes, ratio); referenceMesh = new List <string> { "0.00", "0.01", "0.03", "0.05", "0.08", "0.13", "0.21", "0.32", "0.49", "0.75", "1.13", "1.71", "2.35", "3.00" }; Console.WriteLine("maxRes = {0} ratio = {1}", maxRes, ratio); Console.WriteLine("Original mesh:"); Console.WriteLine(String.Join(", ", mesh.Select(i => String.Format("{0:f2}", i)).ToArray())); EvalGridTest(smoothMesh, referenceMesh); Console.WriteLine(); maxRes = 1; ratio = 1.5; mesh = new List <double> { 0, 0.01, 2.99, 3 }; smoothMesh = RectilinearGrid.SmoothLines(mesh, maxRes, ratio); referenceMesh = new List <string> { "0.00", "0.01", "0.03", "0.05", "0.08", "0.13", "0.21", "0.32", "0.49", "0.75", "0.94", "1.12", "1.31", "1.87", "2.25", "2.51", "2.68", "2.79", "2.87", "2.92", "2.95", "2.98", "2.99", "3.00" }; Console.WriteLine("maxRes = {0} ratio = {1}", maxRes, ratio); Console.WriteLine("Original mesh:"); Console.WriteLine(String.Join(", ", mesh.Select(i => String.Format("{0:f2}", i)).ToArray())); EvalGridTest(smoothMesh, referenceMesh); }
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() ) ) )); }
private void GenerateDirectivitySimulationInput() { // Constants double unit = 1e-3; double c0 = 299792458.0; double lambda0 = c0 / m_f0; double lambdaMin = c0 / (m_f0 + m_fc); Compound simulationSpace = new Compound("space"); Compound solidSpace = new Compound("solid-space"); simulationSpace.Add(solidSpace); Compound dut; if (m_excludeEndo == true) { dut = m_endo.GetModule(m_slotIndex); } else { dut = m_endo; } solidSpace.Add(dut); // modifies dut parent (!) // Set up simulation grid, nf2ff and SAR Logger.WriteInfo("Constructing FDTD simulation grid..."); double airBox = 40; double maxRes = Math.Round(lambdaMin / 20 / unit); double maxRatio = 1.5; RectilinearGrid grid = new RectilinearGrid(); grid.Add(dut.BoundingBox.P1); grid.Add(dut.BoundingBox.P2); #region openems_workaround // openEMS v0.0.31 seems to handle transformations on excitation (lumped port), // SAR and NF2FF simulation components incorrectly. // Applied workarounds: // 1. The entire design is moved so that the antenna feedpoint is in the origin // 2. The SAR and NF2FF boxes are added late, w/o transformations Vector3D antennaPosition = new Vector3D( m_antenna.AbsoluteTransformation.X, m_antenna.AbsoluteTransformation.Y, m_antenna.AbsoluteTransformation.Z); solidSpace.Transformations.Add(new TTranslate(-antennaPosition)); grid.Move(-antennaPosition); grid.Add(new Vector3D(0, 0, 0)); grid.ZLines.Add(-(m_antenna.Parent as CSXCAD.Ara.PCB).Thickness); grid.Sort(); grid.SmoothMesh(m_dutResolution, maxRatio); grid.AddAirbox(airBox); grid.SmoothMesh(maxRes, maxRatio); simulationSpace.Add(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()), lambdaMin / 15 / unit)); #endregion grid.AddPML(8); Simulation fdtd = new Simulation(); fdtd.Excitation = new GaussExcitation(m_f0, m_fc); // Export XDocument doc = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XComment("CyPhy generated openEMS simulation file"), new XElement("openEMS", fdtd.ToXElement(), new XElement("ContinuousStructure", new XAttribute("CoordSystem", 0), simulationSpace.ToXElement(), grid.ToXElement() ) ) ); if (dut is CSXCAD.Ara.Module) { dut.Parent = m_endo; } string openEmsInput = Path.Combine(mainParameters.OutputDirectory, "openEMS_input.xml"); doc.Save(openEmsInput); string nf2ffInput = Path.Combine(mainParameters.OutputDirectory, "nf2ff_input.xml"); var nf2ff = new Postprocess.NF2FF(m_f0); nf2ff.ToXDocument().Save(nf2ffInput); }
public void GenerateFarFieldSimulationInput(string outputDirectory) { Compound simulationSpace = new Compound("space"); Compound solidSpace = new Compound("solid-space"); simulationSpace.Add(solidSpace); Compound dut; if (excludeEndo == true) { dut = endo.GetModule(slotIndex); } else { dut = endo; } solidSpace.Add(dut); // modifies dut parent (!) double airBox = 40; double maxRes = Math.Round(lambdaMin / 20 / unit); double maxRatio = 1.5; RectilinearGrid grid = new RectilinearGrid(); grid.Add(dut.BoundingBox.P1); grid.Add(dut.BoundingBox.P2); Vector3D antennaPosition = new Vector3D( antenna.AbsoluteTransformation.X, antenna.AbsoluteTransformation.Y, antenna.AbsoluteTransformation.Z); solidSpace.Transformations.Add(new TTranslate(-antennaPosition)); grid.Move(-antennaPosition); grid.Add(new Vector3D(0, 0, 0)); grid.ZLines.Add(-(antenna.Parent as CSXCAD.Ara.PCB).Thickness); grid.Sort(); grid.SmoothMesh(dutResolution, maxRatio); grid.AddAirbox(airBox); grid.SmoothMesh(maxRes, maxRatio); simulationSpace.Add(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()), lambdaMin / 15 / unit)); grid.AddPML(8); Simulation fdtd = new Simulation(); fdtd.Excitation = new GaussExcitation(frequency, bandwidth); // Export XDocument doc = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XComment("CyPhy generated openEMS simulation file"), new XElement("openEMS", fdtd.ToXElement(), new XElement("ContinuousStructure", new XAttribute("CoordSystem", 0), simulationSpace.ToXElement(), grid.ToXElement() ) ) ); if (dut is CSXCAD.Ara.Module) { dut.Parent = endo; } System.IO.Directory.CreateDirectory(outputDirectory); string openEmsInput = Path.Combine(outputDirectory, "openEMS_input.xml"); doc.Save(openEmsInput); string nf2ffInput = Path.Combine(outputDirectory, "nf2ff_input.xml"); var nf2ff = new Postprocess.NF2FF(frequency); nf2ff.ToXDocument().Save(nf2ffInput); File.WriteAllText(Path.Combine(outputDirectory, "run_farfield.cmd"), AraRFAnalysis.Properties.Resources.run_farfield); }