-
Notifications
You must be signed in to change notification settings - Fork 1
Interception vs. tower height
This tutorial regards to the automatic calculation of the interception efficiency of a heliostat field as a function of the tower height. The video below shows a step-by-step video on how to use scripts to automatically generate the field and automatically perform simulations for a given range of tower height. The corresponding script is also shown below next to the video.

Script
var file = DataObject();
file.read("heliostats.csv");
function makeHeliostat(parent, name, position, aiming, focus)
{
var nm = parent.createNode(name);
nm.setParameter("translation", position);
nm.setParameter("rotation", "0 0 1 180");
var t = nm.createTracker();
var ta = t.insertArmature("two-axes");
ta.setParameter("primaryShift", "0 0.04 1.5");
ta.setParameter("primaryAxis", "1 0 0");
ta.setParameter("primaryAngles", "-90 90");
ta.setParameter("secondaryShift", "0 0.175 0");
ta.setParameter("secondaryAxis", "0 0 1");
ta.setParameter("secondaryAngles", "-90 90");
ta.setParameter("facetShift", "0 0.125 0");
ta.setParameter("facetNormal", "0 1 0");
var tt = t.getPart("target");
tt.setParameter("aimingPoint", aiming);
var n = nm.createNode("primary");
n = n.createNode("secondary");
n = n.createNode("facet");
n.setParameter("translation", "0 0.125 0");
n.setParameter("rotation", "1 0 0 -90");
var s = n.createShape();
var q = s.insertSurface("Parabolic");
q.setParameter("fX", focus);
q.setParameter("fY", focus);
var p = s.insertProfile("Box");
p.setParameter("uSize", 2.25);
p.setParameter("vSize", 2.25);
var m = s.insertMaterial("Specular");
m.setParameter("slope", "0.002");
var mG = s.getPart("material");
mG.setParameter("ambientColor", "0.65 0.72 0.79");
mG.setParameter("diffuseColor", "0.05 0.05 0.05");
mG.setParameter("specularColor", "0.3 0.25 0.2");
mG.setParameter("shininess", "0.5");
// pylon
n = nm.createNode("pylon");
n.setParameter("scale", "0.05 0.05 1");
s = n.createShape();
m = s.insertMaterial("Transparent");
q = s.insertSurface("Cylinder");
p = s.insertProfile("Rectangular");
p.setParameter("vMin", 0.);
p.setParameter("vMax", 1.5);
var mG = s.getPart("material");
mG.setParameter("ambientColor", "0.5 0.5 0.5");
mG.setParameter("diffuseColor", "0.3 0.3 0.3");
mG.setParameter("specularColor", "0.2 0.2 0.2");
mG.setParameter("shininess", "0.1");
}
function makeTowerMaterial(shape)
{
var mG = shape.getPart("material");
mG.setParameter("ambientColor", "0.47 0.5 0.47");
mG.setParameter("diffuseColor", "0.45 0.45 0.45");
}
function makeTower(nT, xSize, ySize, zSize, zWindow)
{
n = nT.createNode("North");
n.setParameter("translation", "0 0 0");
n.setParameter("rotation", "1 0 0 -90");
s = n.createShape();
p = s.insertProfile("Rectangular");
p.setParameter("uMin", -xSize/2);
p.setParameter("uMax", xSize/2);
p.setParameter("vMin", -(zSize - zWindow));
p.setParameter("vMax", 0);
makeTowerMaterial(s);
n = nT.createNode("South");
n.setParameter("translation", "0 " + (-ySize) + " 0");
n.setParameter("rotation", "1 0 0 90");
s = n.createShape();
p = s.insertProfile("Rectangular");
p.setParameter("uMin", -xSize/2);
p.setParameter("uMax", xSize/2);
p.setParameter("vMin", 0);
p.setParameter("vMax", zSize);
makeTowerMaterial(s);
n = nT.createNode("Top");
n.setParameter("translation", "0 0 " + zSize);
s = n.createShape();
p = s.insertProfile("Rectangular");
p.setParameter("uMin", -xSize/2);
p.setParameter("uMax", xSize/2);
p.setParameter("vMin", -ySize);
p.setParameter("vMax", 0);
makeTowerMaterial(s);
n = nT.createNode("Floor");
n.setParameter("translation", "0 0 " + (zSize - zWindow));
s = n.createShape();
p = s.insertProfile("Rectangular");
p.setParameter("uMin", -xSize/2);
p.setParameter("uMax", xSize/2);
p.setParameter("vMin", -ySize);
p.setParameter("vMax", 0);
makeTowerMaterial(s);
n = nT.createNode("East");
n.setParameter("translation", "" + (xSize/2) + " 0 0");
n.setParameter("rotation", "0 1 0 90");
s = n.createShape();
p = s.insertProfile("Rectangular");
p.setParameter("uMin", -zSize);
p.setParameter("uMax", 0);
p.setParameter("vMin", -ySize);
p.setParameter("vMax", 0);
makeTowerMaterial(s);
n = nT.createNode("West");
n.setParameter("translation", "" + (-xSize/2) + " 0 0");
n.setParameter("rotation", "0 1 0 -90");
s = n.createShape();
p = s.insertProfile("Rectangular");
p.setParameter("uMin", 0);
p.setParameter("uMax", zSize);
p.setParameter("vMin", -ySize);
p.setParameter("vMax", 0);
makeTowerMaterial(s);
}
function makeTower2(nT, xSize, ySize, zSize, zWindow)
{
var wall = 0.2;
n = nT.createNode("North");
n.setParameter("translation", "0 " + (-wall/2) + " " + (zSize - zWindow)/2);
n.setParameter("scale", "" + xSize + " " + wall + " " + (zSize - zWindow));
s = n.createShape();
s.insertSurface("Cube");
makeTowerMaterial(s);
n = nT.createNode("South");
n.setParameter("translation", "0 " + (-ySize + wall/2) + " " + zSize/2);
n.setParameter("scale", "" + xSize + " " + wall + " " + zSize);
s = n.createShape();
s.insertSurface("Cube");
makeTowerMaterial(s);
n = nT.createNode("Top");
n.setParameter("translation", "0 " + (-ySize/2) + " " + (zSize - wall/2));
n.setParameter("scale", "" + xSize + " " + ySize + " " + wall);
s = n.createShape();
s.insertSurface("Cube");
makeTowerMaterial(s);
n = nT.createNode("Floor");
n.setParameter("translation", "0 " + (-ySize/2) + " " + (zSize - zWindow - wall/2));
n.setParameter("scale", "" + xSize + " " + ySize + " " + wall);
s = n.createShape();
s.insertSurface("Cube");
makeTowerMaterial(s);
n = nT.createNode("East");
n.setParameter("translation", "" + (xSize/2 - wall/2) + " " + (-ySize/2) + " " + zSize/2);
n.setParameter("scale", "" + wall + " " + ySize + " " + zSize);
s = n.createShape();
s.insertSurface("Cube");
makeTowerMaterial(s);
n = nT.createNode("West");
n.setParameter("translation", "" - (xSize/2 - wall/2) + " " + (-ySize/2) + " " + zSize/2);
n.setParameter("scale", "" + wall + " " + ySize + " " + zSize);
s = n.createShape();
s.insertSurface("Cube");
makeTowerMaterial(s);
}
function findFocalDistance(pA, pB)
{
vA = pA.split(' ');
vB = pB.split(' ');
dx = vA[0] - vB[0];
dy = vA[1] - vB[1];
dz = vA[2] - vB[2];
d = Math.sqrt(dx*dx + dy*dy + dz*dz);
return 5*Math.round(d/5);
}
function makeField()
{
tn.Clear();
var nodeRoot = NodeObject();
nodeRoot.setName("Script");
var nodeHeliostats = nodeRoot.createNode("Heliostats");
nodeHeliostats.setParameter("translation", "0 0 -1.5");
var nMax = file.rows();
for (var n = 0; n < nMax; n++) {
name = file.array(n)[0];
position = file.array(n)[1];
//focus = file.array(n)[2];
focus = findFocalDistance(position, vRec);
makeHeliostat(nodeHeliostats, name, position, vRec, focus);
}
var nT = nodeRoot.createNode("Tower");
nT.setParameter("translation", "0 0 0");
nT.setParameter("rotation", "0 0 1 5");
makeTower2(nT, 6, 6, zReceiver + 5, 10);
var nR = nodeRoot.createNode("Receiver");
nR.setParameter("translation", vRec);
nR.setParameter("rotation", "-1 0 0 110");
var n = nR.createNode("Plate");
n.setParameter("rotation", "0 0 1 180");
s = n.createShape();
s.setName("Shape")
q = s.insertSurface("Planar");
p = s.insertProfile("Box");
p.setParameter("uSize", 5);
p.setParameter("vSize", 5);
var mG = s.getPart("material");
mG.setParameter("ambientColor", "0.3 0.3 0.3");
mG.setParameter("diffuseColor", "0.1 0.1 0.1");
mG.setParameter("specularColor", "0. 0. 0.");
mG.setParameter("shininess", "0.1");
tn.InsertScene(nodeRoot);
var scene = NodeObject().getScene();
var sp = scene.getPart("world.sun.position");
sp.setParameter("azimuth", 180.);
sp.setParameter("elevation", 90. - 11.27182);
var sa = scene.getPart("world.sun.aperture");
sa.setParameter("disabledNodes", "");
var cm = scene.getPart("world.camera");
cm.setParameter("position", "-105.303 -119.109 117.728");
cm.setParameter("rotation", "33.9011 -31.417");
var tg = scene.getPart("world.terrain.grid");
tg.setParameter("steps", "5 5 5");
tg.setParameter("min", "-50 -25 0");
tg.setParameter("max", "50 100 0");
}
var wMax = 2.25*2.25*155*1000;
print("height [m], efficiency");
for (var h = 10; h <= 45; h += 1)
{
var zReceiver = h;
var vRec = "0.0467 -2.0216 " + zReceiver;
makeField();
var w = tn.FindInterception("//Node/Script/Receiver/Plate/Shape", 100000);
w /= wMax;
print("" + h + ", " + w);
}
Tonatiuh++ MCRT ray-tracer Wiki
Wiki
Getting started
Functionalities
- Tracking systems
- Scripting capabilities
- Field creation from external files
- Accurate component representation
- Design of complex surfaces through functions
- Procedural design of heliostat fields
- Flux analysis
- Materials
- Computer Aided Design (CAD) files import
- Atmospheric transmission
Relevant Papers