I modified the job submit template on OpenLava Web to enable custom job submission forms, it is simple to implement, simply subclass OLWSubmit and include the fields you actually need.

Job Submission Template for Consume Resources
Job Submission Template for Consume Resources

If you want to have custom fields, then you can create them, but you must override _get_args() and return a dictionary of arguments to pass to Submit. You may want to do this generally if you need to build a complex command to pass to Submit from the various fields.

The form will automatically show up in the Submit drop down list, you can defined friendly_name as a class attribute, this will be the text displayed in the drop down. The form’s submit() method is passed any JSON data that was posted, and can be overidden if you need to manipulate it. If you don’t the default for a json request is to pass it directly to the submit function.

Openlava is a GPL fork of LSF 4, and as such is a pretty fully featured job scheduler.  I use frequently LSF in my day job, and use Openlava as a substitute when I just need a familiar environment to test things out.  I felt Openlava lacked a good scripting interface, as (like LSF) it provides only a C API for job management, so I wrote some Python bindings for Openlava.

To test it, I wrote a web interface to Openlava that enables users to view detailed information on jobs, queues, users, and hosts, and for administrators to perform management activities such as opening and closing queues and hosts.  Users can submit new jobs too using a web form.

In addition to the web interface, there is a RESTful API, that can be used to request information programmatically.  To test the API, I wrote a client tools package that removes any complexity from dealing with the remote cluster, and a bunch of command line tools that mimic the behavior of the Openlava CLI enabling remote submission and management of  the remote cluster.

You can view a demo of the web interface, view the documentation, or download the server or client tools from Github.

Invariably, when something goes wrong, I can never quite find the correct CD with the rescue image on it, or the CD drive stops working, or I need to download it, or whatever. Something had to change, so I decided to create a PXE boot environment using pxelinux that would enable me to perform system rescue and hardware maintenance operations just by turning the machine on.

PXE is built into just about any network card firmware these days, even on home PCs, its great for performing remote installations, it is ubiquitous with HPC cluster installations and has been stable for about a decade.

There are plenty of useful tools around for hardware fault finding, maintenance, and system rescue, and I had no intention to create a new one, so I simply took the tools I normally use, and adapted them for PXE.

Features

  • SpinRite – Originally written to adjust the physical layout on the drive, SpinRite has evolved into a wonderful hard disk recovery tool that has some pretty amazing recovery testimonials.
  • CloneZilla – I primarily use this for creating a solid backup of systems that I know I can restore from. It can backup to remote servers over SSH, and i’ve found it to work pretty much flawlessly over the years. It is also good for cloning windows machines and deploying bare metal images in general, but mostly I just use it to create a backup prior to doing anything likely to toast the system.
  • MemTest86 – RAM testing suite, great for finding memory errors and verifying memory upgrades were successful.

DBAN – Probably my most common requirement for this tool, DBAN is a secure disk erasing suite that meeds DoD and other requirements. I resisted the temptation to make autonuke the default option for unknown MAC addresses.

SystemRescueCD – A pretty comprehensive linux environment for fixing things. Comes with various partitioning/recovery and backup/restore tools. I use this rarely, but when I do its pretty invaluable.

NTPasswd – Resets passwords from windows based systems that do not use whole disk encryption. Usually I use this when i need access to a corporate laptop when the help desk are unable to perform an action or fix a problem.

A number of these tools come with additional tools such as FreeDOS, and hardware inventory/diagnostic tools. I included most of them too even though its unlikely I’ll ne

ed them, it was almost no effort.

By default exit and boot from local media.  More common options are nearer the top.  Infrequently used options are in submenus below.
By default exit and boot from local media. More common options are nearer the top. Infrequently used options are in submenus below.

 

Configuration

Most of these tools are Linux based and it was simply a case of moving the files from the Iso to my tftpboot directory, and taking the appropriate configuration from the isolinux.cfg and putting them directly into the pxelinux.cfg/default file.

Most tools have many possible boot options, so I picked the common ones and put them at the top of my menu tree. The rest went into submenus in case they are needed.

tftpd-hpa supports the -s (Secure) option which sets the root to a specified directory, therefore all paths within the configuration are relative to the chroot environment. (/var/lib/tftpboot on Debian based systems)

All files in the tftpboot should be writable only by root, and the tftp daemon should run as an unprivileged user.

DHCPD needs to be configured to allow booting/bootp and with the next-server directive. There are many guides to doing this such as the PXE web site.

Download

I cannot distribute SpinRite as it is proprietary software and I do not own the copyright, however everything else is packaged up ready for download into your tftpboot directory.  To install SpinRite, download SpinRite from GRC, open the Exe and create an ISO.  Once you have created the ISO, put it in tftpboot/spinrite/SpinRite.iso.

By Washington state, I was pretty much down everything I needed and nothing I didn’t.  Water purification still wasn’t quite right, and the weather was getting wetter, so it was time to tent up, and go back to Aqua Mira.  At first I wasn’t quite sure I had made the right decision ditching the bivy – it had faired well in the few storms along the trail, and was very comfortable for the 200 or grams it weighed, however I also know from experience that it is not good for prolonged storms as it simply doesn’t breath well enough and I end up a little sticky by the third night.  Washington rained, it rained a lot, and during an 8 hour thunder storm which comprised part of 8 days of very wet weather, i was very glad for the space and water tight tent.

Backpack

Osprey Aether 65
Sleeping Bag
Marmot Sawtooth 15F Bag
Sleeping Mat
Thermarest NeoAir Lite
Shelter
Rab Survival Zone Bivi, Rain Poncho
Marmot EOS 1p
Stove
JetBoil Sol with larger pot
Cookware
Titanium Utensil, Foldable Camping Knife, Small sponge for wiping clean
Water Treatment
AquaMira and Steripen Freedom
Navigation
Halfmiles PCT maps, PCT App and PDFs on iPad Mini
Entertainment
iPhone
Clothing
Icebreaker underpants 2x, Medium Thickness Woolen Socks 2x, Sherpa Shorts, treated with Permethrin, Icebreaker Merino T-Shirt, Rab Thermals, Patagonia Fleece Pullover, Arc’teryx Alpha SL Soft-shell Rain, Hat
Footwear
Asics GT-2000
First Aid
Medical Tape; Small bottle of iodine; Assorted Elastoplast 10x; Medium adhesive dressing; large non-adhesive dressings 2x; Gauze Bandage 2x.
Hygiene and Care
99% DEET Lotion; Ibuprofen Capsules, 400Mg, lots; Toothbrush; Toothpaste; Dental Sticks; Sunblock;

The steripen broke, the water sensor started malfunctioning and I couldn’t depend on it.  After crater lake I found I wasn’t carrying water, but would drink about 1-2 liters at a time every few miles, so i went back to just Aqua-Mira which works really well in that situation.

The weather in Washington is notoriously wet, so I decided a full tent would be better, the Bivi proved itself in short storms that lasted one or two days.  After 3 days of using a bivi things start to get damp through perspiration.  In severe storms tents have enough room to cook and sit up.  This proved to be a great move in the end as the last two weeks were seriously stormy compared to the rest of the trip.

By mile 702, I’d managed to whittle my pack down a little. My philosophy was to remove anything I hadn’t used within the last week. There were some exceptions to this, mainly first aid kit items. The sierra also required some additional gear, some for the conditions, and others to meet the legal requirements.  I also changed up my cooking and water purification system to better suit what I was doing.

Backpack
Osprey Aether 65
Sleeping Bag
Marmot Sawtooth 15F Bag
Sleeping Mat
Thermarest Self Inflating Sleeping Pad
Thermarest NeoAir Lite
Shelter
Rab Survival Zone Bivi, Rain Poncho
Stove
MSR XGK-II, 1Litre Fuel Bottle
JetBoil Sol with larger pot
Cookware
GSI cookpan, Titanium Utensils, Foldable Camping Knife, Small sponge for wiping clean
Water Treatment
Katadyn Water bottle Filter
AquaMira and Steripen Freedom
Hydration
3L Camelbak Bladder, additional collapsible bladders in desert areas
Navigation
Halfmiles PCT maps, PCT App and PDFs on iPad Mini
Entertainment
IPad Mini with Kindle App
iPhone
Clothing
Icebreaker underpants 2x, Medium Thickness Woolen Socks 2x, North Face Hiking Pants/Shorts, treated with Permethrin, Icebreaker Merino T-Shirt, Rab Thermals, Patagonia Fleece Pullover, Arc’teryx Alpha SL Soft-shell Rain, Waterproof over-trousers, Hat
Footwear
Merrel MOABs
Asics GT-2000
First Aid
Medical Tape; Small bottle of iodine; Assorted Elastoplast 10x; Medium adhesive dressing; large non-adhesive dressings 2x; Gauze Bandage 2x.
Hygiene and Care
99% DEET Lotion; Ibuprofen Capsules, 400Mg, lots; Biodegradable, non-perfumed detergent; Microfibre Cloth; Scissors; Toothbrush; Toothpaste; Dental Sticks; 2nd Skin; Moleskin; Sunblock;

The therm-a-rest had to be replaced a few hundred miles into the desert as it didn’t react too well to cactus thorns, after patching it about 10 times, I thought it was sorted out, but the pockets started to fail internally which caused it to bulge, so I replaced it.  Otherwise it was a great pad.

I replaced the stove mainly because after seeing the convenience of the jet-boil i figured i would cook more, and as it was obvious I could use the jet boil on the rest of the trip (through latin america and beyond) it was a perfect upgrade.  Overall its a bit lighter, but the main advantage is being able to start cooking in about 10 seconds rather than having to set it up and prime the stove etc.  It’s also much less bulky which was nice.

I ditched the filter for Aqua-Mira in Idlewild, this was purely due to the amount of effort required to purify 4 liters of water.  It’s great when you are sipping constantly, but for me I really wanted to chug, and Aqua-Mira enables me to purify 4 liters of water and get hiking again in a few seconds.

In the sierra my water needs changed again, rather than purifying lots of water to last most of the day, I was purifying half a liter of water every few minutes so i switched to a Steripen which is perfect for this as i can just reach down grab a cupful, and 48 seconds later i’m able to drink which meant i never really carried any water.  This meant I could also ditch the bladders and additional bottles.

Before the trip I put a crack in the iPad, and by the time I got to the sierras the digitizer was malfunctioning so I swapped it out for the iPhone, the latter wasn’t quite as good for reading, but otherwise worked perfectly and would have been a better choice overall.

The moabs where comfortable but my feet grew and i found the Asics to be just a bit wider and softer on my feet.  I lost my overtrousers and didn’t replace them, and I found tape worked better than second skin and other blister treatments.

 

Aether 70

Gear is an important choice for the Pacific Crest Trail, and one that has been discussed to death by many. My preference is towards the ultralight philosophy, I have a fairly high tolerance for discomfort, and the simplicity of carrying just enough and no more appeals to me. This of course brings other advantages, the reduced weight to carry means I can go farther in one day, which means I need to carry less food between resupplies.

Backpack
Osprey Aether 70
Sleeping Bag
Marmot Sawtooth 15F Bag
Sleeping Mat
Thermarest Self Inflating Sleeping Pad
Shelter
Rab Survival Zone Bivi, Rain Poncho
Stove
MSR XGK-II, 1Litre Fuel Bottle
Cookware
GSI cookpan, Titanium Utensils, Foldable Camping Knife, Small sponge for wiping clean
Water Treatment
Katadyn Water bottle Filter
Hydration
3L Camelbak Bladder, additional collapsible bladders in desert areas
Navigation
Halfmiles PCT maps, PCT App and PDFs on iPad Mini
Entertainment
IPad Mini with Kindle App
Clothing
Icebreaker underpants 2x, Medium Thickness Woolen Socks 2x, North Face Hiking Pants/Shorts, treated with Permethrin, Icebreaker Merino T-Shirt, Rab Thermals, Patagonia Fleece Pullover, Arc’teryx Alpha SL Soft-shell Rain, Waterproof over-trousers, Hat
Footwear
Merrel MOABs
First Aid
Medical Tape; Small bottle of iodine; Assorted Elastoplast 10x; Medium adhesive dressing; large non-adhesive dressings 2x; Gauze Bandage 2x.
Hygiene and Care
99% DEET Lotion; Ibuprofen Capsules, 400Mg, lots; Biodegradable, non-perfumed detergent; Microfibre Cloth; Scissors; Toothbrush; Toothpaste; Dental Sticks; 2nd Skin; Moleskin; Sunblock;

Much of the gear I already had which dictated many of the choices, I’ve had my backpack since 2005, and whilst its larger than I require, it more than meets the needs for the PCT, ideally a smaller, lighter pack could be used. The same goes for the sleeping bag, the sawtooth has been a great bag, and whilst its on the heavy side, I’ll stick with it. I’ve had it for 4 years, and I suspect this will be the last big trip for it.

I’ve been using the Bivi as an emergency shelter for a couple of years, and it’s proved to add a good few degrees to the bag and keep out the elements. The rain poncho will be used both during the day in wet weather where it will keep me and my pack dry, and at night where combined with my hiking poles it will function as a tarp tent.

The XGK is a great stove for mountaineering, but perhaps not a great choice for backpacking, with the larger fuel bottle it can simmer fairly well, however it is heavy compared to a canister or alcohol stove. I decided to bring this mainly because it is indestructible, and its very easy to see exactly how much fuel is left. As it can burn just about anything, this should enable me to reduce the amount of fuel I need to carry once I get a feel for how much I need. I’ll be starting out with about half a liter in the bottle.

Overall my base weight comes to 14lbs – about 6.5kg which feels pretty good on my back. This does not include water, food, or fuel for the stove however, which will not be insignificant.

The ELM327 IC is a multi-function OBD2 Interpreter that can be used to query information about most relatively new vehicles.  The ELM327 connects to the vehicle using the OBD2 port, and provides an RS232 Interface.   I recently purchased an OBD2 shield form SparkFun which uses an ELM clone, the STN1110.  I wanted to add OBD2 support to Loguino, but first I needed to be able to communicate using the ELM protocol.

Subsequently I created a the ELM327 class, which contains both high level and low level methods to get information from the controller.  The low level class is used to send arbitrary commands to the ELM chip, there are two main methods,

  • getBytes which requests a specific PID and parses the returned bytes into an array of values.
  • runCommand which sends an arbitrary command to the ELM device, and parses the output into a buffer which contains the response from the ELM.

The high level class provides methods to gather metrics from the controller, each method parses the response from the ELM device into the actual value.  The following code illustrates how to use the class:

#define ELM_TIMEOUT 9000
#define ELM_BAUD_RATE 9600
#define ELM_PORT Serial3

byte status;
Elm327 Elm;
status=Elm.begin();
if (status != ELM_SUCCESS){
    Serial.print("Error: ");
    Serial.println(status);
}
int temp;
Serial.print("OBD2 Coolant Temperature: ");
status=Elm.coolantTemperature(temp);
if (status  == ELM_SUCCESS)
{
    Serial.println ("Pass");
    Serial.print(" Value: ");
    Serial.println(i);
}else{   
    Serial.print("Error: ");
    Serial.println(status);
}

byte values[2];
status=getBytes("01","41","0C",values,2);
if (status == ELM_SUCCESS){
    Serial.print("Elm returned: ");
    Serial.print(values[0], HEX);
    Serial.print(" ");
    Serial.println(values[1], HEX);
    Serial.print("Which is: ");
    Serial.print(((values[0]*256)+values[1])/4, DEC);
    Serial.println(" RPM");
}else{   
    Serial.print("Error: ");
    Serial.println(status);
}

char data[20];
status=runCommand("ATI",data,20);
Serial.print("Current version is: ");
Serial.println(data);

Feature requests, bugs, suggestions and other feedback always appreciated.

Mesh refinement is probably one of the hardest components of OpenFOAM, for me this mainly revolves around snappyhexmesh and blockmesh, with one or more STL files exported from SolidWorks as the input.

The first thing to get right is the position in the the blockmesh, you can do this using a transform, or by changing the coordinates in the blockmeshdict.  Then check the refinement box is suitably sized, this one was too small so I made it larger using the refinementbox settings:

refinementBox
      {
          type searchableBox;
          min (-1.0 -1.4 0.0);
          max ( 8.0  1.4 2.5);
      }

Next up is to look at the basic refinement and improve that, currently, the basic mesh looks like this:

Using feature edge detection should align the cells better with the edges of the features.  First we run surfaceFeatureExtract on the STL file, then update snappyhexmesh to use edge detection.

   features
   (
       {
           file "seven.eMesh";
           level 10;
       }
   );

I also turn on feature snapping

nFeatureSnapIter 5;

This makes the edges much cleaner, but the mesh is still too course.

Adding more layers of refinement around the car should improve the mesh some more, to do this we use the addLayersControls settings below:

nSurfaceLayers 3;
expansionRatio 1.3;
finalLayerThickness 0.7;
minThickness 0.25;

Next I make the bounding box slightly finer using blockmesh

blocks
(
     hex (0 1 2 3 4 5 6 7) (80 32 32) simpleGrading (1 1 1)
);

At this point I also need to turn up the max cells a little, and add another refinement level

maxGlobalCells 12000000;
refinementSurfaces
{
     seven
     {
     // Surface-wise min and max refinement level
     level (5 6);
     }
}

 As you would expect, mesh size increases dramatically, as does the time to create the mesh.  The result is improved, however the quality of the mesh is still poor in places, this will need further effort.

The Maxim DS18B20 digital thermometer provides 9-bit to 12-bit Celsius temperature measurements over a 1-Wire interface providing accurate and inexpensive temperature readings.

Kyle Gordon contributed some code that builds on Jim Studt‘s 1-Wire library and Jordan Hochenbaum’s DallasTemperature implementation to integrate into Loguino.

Now you can enable the DS18B20Poller and loguino will capture temperatures from any attached DS180 series sensors.

 

So far my model has used only a single STL file with no patches, and did not take into account the rotation of the wheels and tyres.  I figured out the OpenFOAM part from this thread on CFD-Online, and used paraview and solidworks to modify the model.

I’m working with a large assembly, with each component as its own part which makes getting things in the right format fairly easy.  The first thing to do is save the whole assembly as individual STL files.

As this created a few hundred files, all with spaces in the name, I opened them in paraview and used the Append Geometry filter to create a single object for the front axle, rear axle, and everything else.  For each of the new geometries, i added an Extract Surface filter.

As I managed to get my solid model in a strange location in Cartesian space, I performed a translation to rotate and move them to the middle of the bounding box.  I could have also moved the bounding box in blockmeshdict.  I then saved the three surfaces as chassis.stl, faxle.stl, and raxle.stl. Use the ascii file format.

Paraview calls the solids ascii (I’m assuming binary if you use the binary file format) since these dictate the name of the patch that snappy will create, it makes sense to rename these based on their file names.  These then need to be concatenated into a single file.  I used some sed foo to do this.

This then gives me three patches, seven_chassis, seven_faxle and seven raxle.  These need to be defined in the initial condition for U.

Originally there was just a single definition:

"seven_*"
    {
         type            fixedValue;    
         value           uniform (0 0 0);
    }

However, we now need to define the three patches explicitly.  The first is easy, as its the everything else part.

"seven_chassis"
    {
         type            fixedValue;    
         value           uniform (0 0 0);
    }

However, for the rotating boundary, we need to know a few more things.  The first is the origin of the rotation, I created a point in the center of the axle and manually applied the appropriate transformation to get the center of rotation.  As I’m assuming that there is zero toe and zero camber, this is trivial.  In the future I may wish to improve on the model in which case I will have four patches, and I’ll add some sketches to the model to work out the correct axis.

The axis of rotation in my model is the y axis, which again is trivial in this case.

Lastly I needed to work out the speed the wheels are rotating at.  I am modelling the car at a speed 40ms−1, and Omega, the boundary condition is measured in rads/second.

First we calculate the distance travelled in one revolution of the wheel.  I have 13 rims with 205×60 profile tyres. This gives a circumference of 1.8146Meters giving 22.04 revolutions per second.  1 Revolution is 2pi radians, giving 138.5rads/sec.

"seven_faxle"
      {
          type            rotatingWallVelocity;
          origin          ( 0.839 0 0.2775 );
          axis            ( 0 1 0 );
          omega           138.5;
      }
      "seven_raxle"
      {
          type            rotatingWallVelocity;
          origin          ( 2.753 0 0.2775 );
          axis            ( 0 1 0 );
          omega           138.5;
      }