Updates and Results Talks and Posters Advice Ideas Important Figures Write-Ups Outreach How-To Funding Opportunities GENETIS
  GENETIS  ELOG logo
Message ID: 205     Entry time: Mon Mar 20 17:32:42 2023
Author: Alex M 
Subject: GENETIS Hackathon Day 1 

Today was the first day of the GENETIS Hackathon. We are spending several days this week specifically tackling the PUEO project to get it into full form (or close to it). Here is a progress update after day 1.

 

Alex

I am working on the xmacro script for the ANITA antenna. Before today, we had a working xmacro script to make the geometry of the ANITA horn antenna. Now I am trying to modify it to make it 1) more true to the actual ANITA antenna (in terms of which parts are electrically connected) and 2) add in the power source and sensors so that we can get simulation results. I've attached the xmacro script here along with a picture of the geometry and some gain patterns. There are four ridges in the antenna. They are all connected by the outer walls of the antenna. However, only the ones directly across from each other are connected by a load (in this case, a power source, since we simulate as a radiator). So we have two power sources, one connected each "ridge bicone". 

In making this, I have generated some gain patterns. I want to test a few cases to see if the results coming from XF seem reasonable, though I don't know what I should expect the gain pattern to look like when I've done things correctly. Here are the options I'll compare:

  1. Just use one "ridge bicone".
  2. Use two "ridge bicones" with the walls but just one power source.
  3. Use two "ridge bicones" without the walls and two power sources.
  4. Use the full form, with two "ridge bicones", walls, and two power sources.

Case (4) is the one I expect to be correct. However, when I simulate that, I get a slightly asymmetric gain pattern compared to what I expect (I expect symmetry across the "ridge bicones"). You can see from the attached image that there is a strange preference in one corner. My guess is that this has to do with which ridges are set to be ground and which are set to 1V (the potential). Feel free to ask me for more details about these figures/scripts on slack and I'll fill them in on here. I'll clean up the script and add in full test cases later this week.

The image of the antenna I attached is a bird's eye view. The green lines represent the power sources I've connected between the ridges. They do appear to overlap, but my understanding is that they are not actually affecting each other (they should just be a representation of the power sources). 

The image of a gain pattern (which is 3D and also a bird's eye view) is for the case of the antenna with both power sources and the walls remaining (the antenna is still shown too, to demonstrate the asymmetry of the gain pattern). This is well outside of the frequency range ANITA cares about (83 MHz), and I haven't looked closely at the higher frequencies yet, but I still am surprised by the asymmetry. I'll update tomorrow with more gain patterns to compare.

 

Dylan and Jacob

Dylan and Jacob are working on the bash scripts for the PUEO loop. They are taking the parts of the bicone loop that are specific to ARA/bicones and changing them to be specific to the PUEO loop. 

All the bash scripting outside of implementing the new software we’re developing should now be complete (we just need to debug when we do test runs). The new GA is implemented into the PUEO loop. We tried and failed to build a version of pueoSim on our own. Will has provided us with a precompiled version and instructions for installing it on our users as well as access to the necessary pueoBuilder repo. Jacob and Dylan are scheduled to go through the installation with him on Thursday at 4pm in his office, M2024.

We have also found that peuoSim currently only outputs root files. So, we will need to create a conversion script or modify pueoSim for when we implement it into the loop. Currently, using IceMC looks to be the easiest way to get a test run going. For the next steps, we have a plan for making IceMC read in a variable file path name to avoid recompiles and issues with parallelization (Alex has given us the path to look at how ARA does it). Then, we will work on installing pueoSim and testing its current viability.

 

Bryan

Upon checking the existing plotting scripts used for previous GENETIS work, it appears that they can be used for PUEO with minimal changes. In order to test the plotting scripts, sample output data from the PUEO loop is needed, or at least test data that mimics the form of the output for the PUEO loop. After more progress is made with installing an MC package and the PUEO loop can be run to produce test outputs, the plotting scripts can be tested and implemented in the bash script.

Attachment 1: ANITA_Antenna_Project.xmacro  16 kB  Uploaded Mon Mar 20 18:53:54 2023  | Hide | Hide all | Show all
App.getActiveProject().getGeometryAssembly().clear();
var freq = [83.33, 100.00, 116.67, 133.33, 150.00, 166.67, 183.34, 200.00, 216.67, 233.34, 250.00, 266.67, 283.34, 300.00, 316.67, 333.34, 350.00, 366.67, 383.34, 400.01, 416.67, 433.34, 450.01, 466.67, 483.34, 500.01, 516.68, 533.34, 550.01, 566.68, 583.34, 600.01, 616.68, 633.34, 650.01, 666.68, 683.35, 700.01, 716.68, 733.35, 750.01, 766.68, 783.35, 800.01, 816.68, 833.35, 850.02, 866.68, 883.35, 900.02, 916.68, 933.35, 950.02, 966.68, 983.35, 1000.00, 1016.70, 1033.40, 1050.00, 1066.70] 
CreatePEC();
var units = " cm";
num_ridges = 4; // either 2 or 4
// Make the walls and a ridge
build_walls(10,1,30);
// Note that to avoid overlap, we need x0 >= y0
x0=0.04001; // previously 0.04
y0=0.04; // previously 0.04
build_ridges(x0, y0, 0.0, 0.1, 0.06, 0.3, 0.26, 0.1, 0.1, 1); 
CreateAntennaSource();
CreateGrid();
CreateSensors();
CreateAntennaSimulationData();
QueueSimulation();

// Try making copies of the ridge
var new_ridges = new EllipticalPattern();
Output.println(new_ridges.getInstances());
new_ridges.setInstances(7);
//new_ridges.clone();
//Output.println(new_ridges);

// Makes the outer walls of the horn antenna
// S is the side length of the bottom of the wall
// a is the coefficient for the linear function the walls extrude according to
function build_walls(S,m,H) 
{
	// Make the edges to define the square
	var edge1 = Line( new Cartesian3D(-S + units,-S + units, 0), new Cartesian3D(-S + units, S + units, 0));
	var edge2 = Line( new Cartesian3D(-S + units, S + units, 0), new Cartesian3D(S + units, S + units, 0));
	var edge3 = Line( new Cartesian3D(S + units,S + units, 0), new Cartesian3D(S + units, -S + units, 0));
	var edge4 = Line( new Cartesian3D(S + units,-S + units, 0), new Cartesian3D(-S + units, -S + units, 0));
	
	// Declare sketches to be made from the edges
	var wallSegment = new Sketch();
	var bottomSegment = new Sketch();
	wallSegment.addEdge(edge1);
	wallSegment.addEdge(edge2);
	wallSegment.addEdge(edge3);
	wallSegment.addEdge(edge4);
	bottomSegment.addEdge(edge1);
	bottomSegment.addEdge(edge2);
	bottomSegment.addEdge(edge3);
	bottomSegment.addEdge(edge4);

	// Let's start by making the bottom
	var bottomCover = new Cover(bottomSegment);
	var bottomRecipe = new Recipe();
	bottomRecipe.append( bottomCover );
	var bottomModel = new Model();
	bottomModel.setRecipe( bottomRecipe );
	// Add the surface
	//var bottom = App.getActiveProject().getGeometryAssembly().append(bottomModel);
	//bottom.name = "Bottom square";

	// Now we need to extrude the edges to get height
	var walls = new Extrude( wallSegment, H + units);				// Makes an Extrude
	var wallOptions = walls.getOptions();						// Gives the possible options for 
	// We will use the draft law option to extrude linearly
	wallOptions.draftOption = SweepOptions.DraftLaw;			// allows for draftlaw
	wallOptions.draftLaw = "("+m+"*x)";							// Set the expression for the extrude
	wallOptions.draftOption = 4;								// 4 indicates we use draftlaw
    //Walter - Change the gap type to Extended to get the desired shape
	wallOptions.gapType = SweepOptions.Extended; 				// I actually don't like this when we have x^2, but it doesn't do much for just x
    //Walter - Create a shell instead of a solid part
	wallOptions.createSolid = false;							// This way the shape isn't filled in
	walls.setOptions ( wallOptions );							// Sets the settings we assigned above

	// Make a recipe for a model
	var wallRecipe = new Recipe();
	wallRecipe.append(walls);
	var wallModel = new Model();
	wallModel.setRecipe(wallRecipe);
	wallModel.name = "Outer Walls";
	wallModel.getCoordinateSystem().translate(new Cartesian3D(0,0,0));	// Makes the model start at the origin

	// Set the material for these parts
	var wallProject = App.getActiveProject().getGeometryAssembly().append(wallModel);	// Adds the model to the project
	var pecMaterial = App.getActiveProject().getMaterialList().getMaterial( "PEC" );	// Makes the material available
	App.getActiveProject().setMaterial( wallProject, pecMaterial );						// Sets the material
	//App.getActiveProject().setMaterial( bottom, pecMaterial );						// Sets the material

}

// A function to build the inner ridges
// Here are the arguments, which are primarily used when making the LawEdges
// Bottom x distance from center
// Bottom y distance from center
// Top x distance from center
// Top y distance from center
// Full x
// Full y
// Full height
function build_ridges(x_0, y_0, z_0, x_f, y_f, z_f, tau, beta, S, m)
{

//	build_ridges(0.04, 0.04, 0.0, 0.1, 0.06, 0.3, 0.26, 0.1, 0.1, 1);

	// Logarithmic slopes
	//var Log1 = new LawEdge( "0.04 + u", "0.04 + 0.02/0.26*u", "1/10*ln((exp(3)-1.0)/0.26*u+1.0)", 0, 0.26); // alpha = z_max/beta
	//var Log2 = new LawEdge( "0.04 + u", "-0.04 - 0.02/0.26*u", "1/10*ln((exp(3)-1.0)/0.26*u+1.0)", 0, 0.26);

	var Log1 = new LawEdge( ""+x_0+" + ("+z_f+"-"+x_0+")/"+tau+"*u", ""+y_0+" + ("+y_f+"-"+y_0+")/"+tau+"*u", ""+beta+"*ln((exp("+z_f+"/"+beta+")-1.0)/"+tau+"*u+1.0)", 0, tau); // alpha = z_max/beta
	var Log2 = new LawEdge( ""+x_0+" + ("+z_f+"-"+x_0+")/"+tau+"*u", "-"+y_0+" - ("+y_f+"-"+y_0+")/"+tau+"*u", ""+beta+"*ln((exp("+z_f+"/"+beta+")-1.0)/"+tau+"*u+1.0)", 0, tau);


	// Inner straight slopes 
	var IS1 = new LawEdge( ""+x_0+" + ("+z_f+"-"+x_0+")/"+tau+"*u", ""+y_0+" + ("+y_f+"-"+y_0+")/"+tau+"*u", "("+z_f+"-"+z_0+")/"+tau+"*u", 0, tau); // a_0 + at, b_0 + bt, c_0 + ct
	var IS2 = new LawEdge( ""+x_0+" + ("+z_f+"-"+x_0+")/"+tau+"*u", "-"+y_0+" - ("+y_f+"-"+y_0+")/"+tau+"*u", "("+z_f+"-"+z_0+")/"+tau+"*u", 0, tau);

	// Bottom line
	var BL1 = new LawEdge(""+x_0+" + ("+x_f+"-"+x_0+")/"+tau+"*u", ""+y_0+"", ""+z_0+"", 0, tau);
	var BL2 = new LawEdge(""+x_0+" + ("+x_f+"-"+x_0+")/"+tau+"*u", "-"+y_0+"", ""+z_0+"", 0, tau);

	// Top line
	var TL1 = new LawEdge(""+z_f+" + "+x_f+"/"+tau+"*u", ""+y_f+"", ""+z_f+"", 0, tau);
	var TL2 = new LawEdge(""+z_f+" + "+x_f+"/"+tau+"*u", "-"+y_f+"", ""+z_f+"", 0, tau);

	// Outer Straight slopes
	var OS1 = new LawEdge( ""+x_f+" + "+z_f+"/"+tau+"*u", ""+y_0+" + ("+y_f+" - "+y_0+")/"+tau+"*u", ""+z_f+"/"+tau+"*u", 0, tau);
	var OS2 = new LawEdge( ""+x_f+" + "+z_f+"/"+tau+"*u", "-"+y_0+" - ("+y_f+" - "+y_0+")/"+tau+"*u", ""+z_f+"/"+tau+"*u", 0, tau);

	// Inner top line
	var ITL = new LawEdge( ""+z_f+"", "-"+y_f+" + 2*"+y_f+"/"+tau+"*u", ""+z_f+"", 0, tau);

	// Outer top line
	var OTL = new LawEdge( ""+x_f+" + "+z_f+"", "-"+y_f+" + 2*"+y_f+"/"+tau+"*u", ""+z_f+"", 0, tau);

	// Inner bottom line
	var IBL = new LawEdge( ""+x_0+"", "-"+y_0+" + 2*"+y_0+"/"+tau+"*u", ""+z_0+"", 0, tau);

	// Outer bottom line
	var OBL = new LawEdge( ""+x_f+"", "-"+y_0+" + 2*"+y_0+"/"+tau+"*u", ""+z_0+"", 0, tau);

	// Make the sketches
	var straightEdge1 = new Sketch(); 	// All straight edges (IS1, BL1, TL1, OS1)
	var straightEdge2 = new Sketch(); 	// All straight edges (IS2, BL2, TL2, OS2)	
	var curvedLog1 = new Sketch(); 		// Logarithmic edge (IS1 and Log1)
	var curvedLog2 = new Sketch(); 		// Logarithmic edge (IS2 and Log2)
	var topRectangle = new Sketch(); 	// Top rectangle
	var bottomRectangle = new Sketch(); // Bottom rectangle

	// Add the edges to the sketches
	straightEdge1.addEdges( [IS1, BL1, TL1, OS1] );	// Inner straight slope
	curvedLog1.addEdges( [IS1, Log1] );				// Right logarithm part
	straightEdge2.addEdges( [IS2, BL2, TL2, OS2] ); 	// Inner straight slope
	curvedLog2.addEdges( [IS2, Log2] );			 	// Left logarithm part
	topRectangle.addEdges( [ITL, OTL, TL1, TL2] );		// Top rectangle
	bottomRectangle.addEdges( [IBL, OBL, BL1, BL2] );	// Bottom Rectangle

	//WALTER - The Elliptical pattern is added as a recipe to the parts
	//In this case the location of the center and direction of the normal are simple, but for more complex scenarios, may need to use mroe functionality to find them.
	var ePattern = new EllipticalPattern();
	ePattern.setCenter(new CoordinateSystemPosition(0,0,0));
	ePattern.setNormal(new CoordinateSystemDirection(0,0,1));
	ePattern.setInstances(num_ridges);
	ePattern.setRotated(true);

	var cov = new Array();
	cov.push(new Cover(straightEdge1));
	cov.push(new Cover(straightEdge2));
	cov.push(new Cover(curvedLog1));
	cov.push(new Cover(curvedLog2));
	cov.push(new Cover(topRectangle));
	cov.push(new Cover(bottomRectangle));

	var pecMaterial = App.getActiveProject().getMaterialList().getMaterial( "PEC" );

	//WALTER - We can loop over all our parts and add them to the project as follows.  You can use similar concepts above.
	models = new Assembly();
	for(var w = 0; w < cov.length; w++)
	{
		var r = new Recipe();
		r.append(cov[w]);
		r.append(ePattern);
		var m = new Model();
		m.setRecipe(r);
		m.name = "Test Surface " + (w+1);
		//WALTER - Seperate array for the models, though we could just get them from the GemoetryAssembly again
		models.append(m);
		App.getActiveProject().setMaterial( m, pecMaterial );

	}

	// Work on the loft
	var vertex_position1 = curvedLog1.getPosition(curvedLog1.getVertexIds()[0]);	
	var vertex_position2 = curvedLog2.getPosition(curvedLog2.getVertexIds()[0]);

	var loft = new Loft(models.at(2).pickFace(new Cartesian3D (0, 0, 0), vertex_position1, 0.5), "0.0", models.at(3).pickFace(new Cartesian3D(0,0,0), vertex_position2, 0.5), "0.0");
	loft.setPart1(models.at(2));
	loft.setPart2(models.at(3));
		
	var r12 = new Recipe();
	r12.append( loft );
	r12.append(ePattern);
	var m12 = new Model();
	m12.setRecipe( r12 );
	m12.name = "Loft 1";
	models.append(m12);

	//WALTER - append the assembly to the project, then loop over it to assign the material
	var assembly = App.getActiveProject().getGeometryAssembly().append(models);
	for(x = 0; x < assembly.size(); x++)
	{
		Output.println(assembly.at(x));
		App.getActiveProject().setMaterial( assembly.at(x), pecMaterial );
	}

}



// CreatPEC Function
function CreatePEC() //borrowed from XF demo
{
    //Make the material.  We will use PEC, or Perfect Electrical Conductor:
    var pec = new Material();
    pec.name = "PEC";
    var pecProperties = new PEC();      // This is the electric properties that defines PEC
    var pecMagneticFreespace = new MagneticFreespace();     // We could make a material that acts as PEC and PMC, but in this case we just care about electrical components.
    var pecPhysicalMaterial = new PhysicalMaterial();
    pecPhysicalMaterial.setElectricProperties( pecProperties );
    pecPhysicalMaterial.setMagneticProperties( pecMagneticFreespace );
    pec.setDetails( pecPhysicalMaterial );
    // PEC is historically a "white" material, so we can easily change its appearance:
    var pecBodyAppearance = pec.getAppearance();
    var pecFaceAppearance = pecBodyAppearance.getFaceAppearance();  // The "face" appearance is the color/style associated with the surface of geometry objects
        pecFaceAppearance.setColor( new Color( 255, 255, 255, 255 ) );  // Set the surface color to white. (255 is the maximum intensity, these are in order R,G,B,A).
    // Check for an existing material
    if( null != App.getActiveProject().getMaterialList().getMaterial( pec.name ) )
    {
            App.getActiveProject().getMaterialList().removeMaterial( pec.name );
    }
	    App.getActiveProject().getMaterialList().addMaterial( pec );
}

function CreateAntennaSource()
{
    // Here we will create our waveform, create our circuit component definition for the feed, and create
    // a CircuitComponent that will attach those to our current geometry.
    var waveformList = App.getActiveProject().getWaveformList();
        // clear the waveform list
	    waveformList.clear();

    // Create a gaussian derivative input wave
    var waveform = new Waveform();
    var GDer = new GaussianDerivativeWaveformShape ();
    GDer.pulseWidth = 2e-9;
    waveform.setWaveformShape( GDer );
    waveform.name ="Gaussian Derivative";
    var waveformInList = waveformList.addWaveform( waveform );

    // Now to create the circuit component definition:
    var componentDefinitionList = App.getActiveProject().getCircuitComponentDefinitionList();
    // clear the list
    componentDefinitionList.clear();

    // Create our Feed
    var feed1 = new Feed();
    var feed2 = new Feed();

    feed1.feedType = Feed.Voltage; // Set its type enumeration to be Voltage.
    //feed2.feedType = Feed.Voltage; // Set its type enumeration to be Voltage.

    // Define a 50-ohm resistance for this feed
    var rlc = new RLCSpecification();
    rlc.setResistance( "50 ohm" );
    rlc.setCapacitance( "0" );
    rlc.setInductance( "0" );
    feed1.setImpedanceSpecification( rlc );
    feed1.setWaveform( waveformInList );  // Make sure to use the reference that was returned by the list, or query the list directly
    feed1.name = "50-Ohm Voltage Source";
    var feedInList = componentDefinitionList.addCircuitComponentDefinition( feed1 );


	feed2.setImpedanceSpecification( rlc );
    feed2.setWaveform( waveformInList );  // Make sure to use the reference that was returned by the list, or query the list directly
    feed2.name = "50-Ohm Voltage Source 2";
    var feedInList = componentDefinitionList.addCircuitComponentDefinition( feed2 );

    // Now create a circuit component that will be the feed point for our simulation
    var componentList = App.getActiveProject().getCircuitComponentList();
    componentList.clear();

    var component1 = new CircuitComponent();
	var component2 = new CircuitComponent();

	component1.name = "Source";
	component2.name = "Source";

    component1.setAsPort( true );
    component2.setAsPort( true );
    // Define the endpoints of this feed - these are defined in world position, but you can also attach them to edges, faces, etc.
    var coordinate1 = new CoordinateSystemPosition( -x0, 0, 0);
    var coordinate2 = new CoordinateSystemPosition( x0, 0, 0);
	var coordinate3 = new CoordinateSystemPosition( 0, -x0, 0);
    var coordinate4 = new CoordinateSystemPosition( 0, x0, 0);
    component1.setCircuitComponentDefinition( feed1 );
... 84 more lines ...
Attachment 2: ANITA_Horn.png  10 kB  Uploaded Mon Mar 20 18:55:49 2023  | Show | Hide all | Show all
Attachment 3: ANITA_Gain_Pattern_Both_Sources.png  143 kB  Uploaded Mon Mar 20 19:04:55 2023  | Hide | Hide all | Show all
ANITA_Gain_Pattern_Both_Sources.png
ELOG V3.1.5-fc6679b