600.107 Introduction to Programming in Java
Homework #7 -- Due 11:30pm on Wednesday 11/1

Overview

The purpose of this assignment is to develop skills with nested loops, arrays, writing static methods and working with files. As a side effect, you'll learn a little bit about heat transfer in metal objects. See the Background section below for an introduction before reading the assignment specifications. There is no starter java program file provided for this assignment. We will provide a zip file for this assignment that has some sample input files in it, and one sample output file to show you the format and expected results. NOTE: This is a significant homework and is really important to do as preparation for the next project.

Deliverables: Submit a zip file named Hw7-jhedLogin.zip, substituting your actual JHED login as the second part of the file name. Make sure that this includes your solution to both parts, named Hw7a.java and Hw7b.java. Both files should have a main method, as well as helper methods so that the processing is divided up into smaller chunks. Remember to make your solutions fully checkstyle compliant.


Part A: Heat Rod

Imagine a metal rod of negligible thickness sticking through a building's brick wall. The inside of the building is cooled to 70 degrees Fahrenheit, while the outside is a sweltering 100 degrees. To keep things simple, we'll assume that the wall itself has no influence whatsoever on the temperature of the rod. The purpose of this program is to simulate the temperature distribution along the rod inside the wall (where it can't be measured), between the heated end and the cooled end. You will do this by repeatedly averaging temperatures along the rod until there is minimal change from one iteration to the next, as measured with an epsilon value of 0.01. At the end of the simulation, the temperature should increase linearly from 70.0 degrees to 100.0, for this particular example.

The overall operation of your program must be as follows: prompt the user for the cool and hot temperatures that will be applied to opposite ends of the rod. Also prompt the user for an integer length of the rod. Your program must then print the temperatures along the rod for the initial state and every averaging iteration, one round per line, until they stabilize for our epsilon value of 0.01. Make sure to print the values so that they line up nicely in columns of width 8 exactly, and all values have exactly 3 digits after the decimal place. The last two lines of output will show that there are no more changes within our epsilon value. However, because of precision issues and rounding by printf, you might see slight variations in the last digit displayed. Try the simulation out with a few different sets of values to get a feel for how the temperatures get distributed. Here is a (very small) sample run:

Enter cool and hot temperatures: 70 100
What is the rod length? 5
Temperature distribution simulation:
  70.000   0.000   0.000   0.000 100.000
  70.000  35.000   0.000  50.000 100.000
  70.000  35.000  42.500  50.000 100.000
  70.000  56.250  42.500  71.250 100.000
  70.000  56.250  63.750  71.250 100.000
  70.000  66.875  63.750  81.875 100.000
  70.000  66.875  74.375  81.875 100.000
  70.000  72.188  74.375  87.188 100.000
  70.000  72.188  79.688  87.188 100.000
  70.000  74.844  79.688  89.844 100.000
  70.000  74.844  82.344  89.844 100.000
  70.000  76.172  82.344  91.172 100.000
  70.000  76.172  83.672  91.172 100.000
  70.000  76.836  83.672  91.836 100.000
  70.000  76.836  84.336  91.836 100.000
  70.000  77.168  84.336  92.168 100.000
  70.000  77.168  84.668  92.168 100.000
  70.000  77.334  84.668  92.334 100.000
  70.000  77.334  84.834  92.334 100.000
  70.000  77.417  84.834  92.417 100.000
  70.000  77.417  84.917  92.417 100.000
  70.000  77.458  84.917  92.458 100.000
  70.000  77.458  84.958  92.458 100.000
  70.000  77.479  84.958  92.479 100.000
  70.000  77.479  84.979  92.479 100.000
  70.000  77.490  84.979  92.490 100.000
  70.000  77.490  84.990  92.490 100.000
  70.000  77.495  84.990  92.495 100.000
        

Approach

Imagine that the rod is divided into a bunch of tiny segments along the portion inside the wall, sort of like a tootsie roll. Each segment will have it's own temperature value that you'll store in array of floating point numbers. The first element in the array will be the cool side and the last element in the array will be the hot side - these never change! Initially it doesn't matter what the temperature of the inner segments is set to, so just set them all to 0.0.

Now, in order to simulate the temperature distribution, you need to repeatedly average the temperatures to the left and right of each inner segment (cell) in order to compute its new value. Do not include the cell's value in the average - only it's neighbors. You have to do that for all the inner cells in our rod (the first and last don't change). It's important that you average the two neighbors from the prior temperature distribution into a new temperature distribution. In other words, you'll have an array with the prior temperatures, and use those temperatures to compute a new set of average temperatures (store in another array). After all the new values have been computed your program should print them, and then, copy the new values into the prior array for the next iteration.

For example, if you start with a rod segment that only has 5 segments, the initial values should be

        70.0 0.0 0.0 0.0 100.0
      
After the first round of averaging, the new values (remember, in a different array) will be
        70.0 35.0 0.0 50.0 100.0
      
The middle value is still 0.0 because it is the average of its neighbors from the first array (0.0 and 0.0). Now the new values become the prior and we do another round:
        70.0 35.0 42.5 50.0 100.0
      
Reassign again from new to prior, and average again:
        70.0 56.25 42.5 72.25 100.00
      

As you notice, only some values change on each iteration, but not necessarily all of them. How will we know when to stop distributing temperatures? In other words, how many rounds of averaging are enough? We can stop when the values in the prior array are roughly the same as the corresponding values in the new array, meaning that they are no longer changing significantly. Since these values are floats, we anticipate precision errors. Let's say two values are the "same" if they are strictly less than epsilon=0.01 of each other for the purposes of this part of the project. Therefore, two arrays are "equivalent" if every pair of corresponding values (those at the same position) are the "same".

Implementation Requirements

You are required to use at least three static helper methods in order to break this processing into smaller steps. These must include a boolean method that determines if two floats are the "same" for a given epsilon value, and also one that checks whether two arrays of floats are "equivalent" based on an epsilon parameter. Both of these methods should return true or false values. (Hint - the array "equivalent" method should call the "same" method on individual cells to help with processing.) You must also have a method to print the contents of an array, with the necessary formatting. You may add and use other methods as needed.

Part B: Heat Plate

The Simulation Extension: Now we are going to generalize the problem from Part A, applying the simulation to rectangular metal plates, such as ones we generated in a prior assignment. Each plate has temperature restricted cells and unrestricted cells. The restricted ones are fixed to be either hot ('H') or cold ('C'). They cannot change because we are assuming that either a heat source or a cold source are being applied to them with constant temperatures. However, the goal of this assignment is to simulate the temperature distribution of the unrestricted cells ('.') until the heat plate temperature distribution stabilizes. As above, we consider the simulation to be done when all the cells from the "prior" plate are strictly within some epsilon of the corresponding cells in the new array. However, this time the epsilon value might vary from one simulation to another. Your solution must have several methods in addition to main to help with the processing.

Similar to Part A, you will get user input for the hot ('H') and cold ('C') temperatures. Unrestricted cells should be initialized to 0. You will also get user input for the epsilon value to use to determine when to stop the simulation. Your program must also get the name of an input file as input. This input file must be a plain text file in the same format that we generated for HW6: the first line contains the height (rows) and width (column) dimensions of the plate. The subsequent lines in the file contain 'H', 'C' or '.' values for each cell in the heatplate.

Unlike Part A, we are now going to write the results to a file (not the screen). The first line of the output file must contain the epsilon value, then a blank line. Next print the first set of temperatures for the entire heat plate (initial values). Follow this with another blank line, and then the last set of temperatures (final distribution) for the simulation. Use exactly five digits of precision after the decimal point for each temperature. The name of each output file should start the same as the name of the input file, with the cold and hot temperatures inserted before the ".txt" with '_' separators. For example, if the program is run on input file "plate.txt" with temperatures 40 and 90, then the output file must be named "plate_40_90.txt". Make sure that your output is formatted nicely, with the temperatures lined up in columns of width 10 (not 8) and exactly 5 digits (not 3 as in Part A) after the decimal place for each.

This problem is trickier than the one dimensional heat rod for several reasons. First of all, you'll need to work with two-dimensional arrays instead of one dimension. Secondly, each input file will have different positions for the restricted cells (H,C) and the unrestricted ones. So in addition to the prior and new arrays that are holding and averaging the temperatures, you'll need to keep an array (of booleans?) that you can check to see if a cell is restricted or not. Remember, only the temperatures of the unrestricted cells should be changing.

Lastly, each cell will have potentially 4, but possibly only 3 or 2 neighbors to be averaged. As in part A, the cell's prior value is not part of what gets averaged. Here we consider a neighbor to be a cell to the north, south, east or west of the one being computed; diagonally adjacent cells will not be included in the averages either. However, if the average is being computed for a corner cell, it only has 2 neighbors. If it's being computed for an edge cell, it has 3 neighbors. All interior cells have 4 neighbors. Consider writing a subroutine (method) that returns the neighbor average for a cell given the row and column indices and the (prior) array of temperatures.

Because of the complexity of this problem, you should think about how to handle the simulation in pseudocode before writing your Java code. You will also want to sketch out helpful methods and make an incremental development plan. For example, first write a program to get the input and create the output file. Then add the first table of initial values to the output file. You can also temporarily write values to the screen as the simulation proceeds to make it easier to see what is going on for debugging purposes.

User Interface: You will need to get user input for the temperatures, epsilon value, and input filename. Write the output filename to the screen when the simulation ends, but save the actual simulation data to the file only as directed above. Here is a brief sample run:

  Enter cold and hot temperatures: 30 95
  Enter epsilon value < 1: .0001
  Enter input filename: plate.txt
  Output is in file: plate_30_95.txt
  

In the assignment zip file we have provided you with several files that you can use as potential input files (named *.txt). You also likely have several of your own lying around as a result of executing your solution to HW6. We've also included a sample output file to clarify the formatting requirements: plate_25_100.txt is the output from using plate.txt as the input file with temperatures 25 (cold) and 100 (hot).

Incremental Development: Because this problem can be tricky and has several layers, here are recommended stages that you should attempt, one at a time. Do not try to do another stage if what you've attempted is not yet working perfectly. You should probably be using one or more methods to handle the processing for each stage.

Background

[Credit to Peter Froehlich for this explanation and the assignment concept.] If you're interested, here is some background explaining a bit about what's going on with the heat transfer that we were simulating. First off, what is heat? It's probably in bad taste to start with a joke about the miserably humid 100 degree Baltimore summer or refer to a popular 2009 tune by Nelly, so let's be more scientific.

Thermodynamics tells us that heat---on a macroscopic level---is energy: the internal energy of a system is the sum of heat supplied to the system and the amount of work done on it. Statistical mechanics tells us that heat---on a microscopic level---is movement: the atoms of a system move (or vibrate) faster the hotter the system happens to be.

Heat can be transferred in various ways:

We'll only consider heat transfer by conduction for this project, and we'll also restrict our attention to solids.

Join us in a Gedankenexperiment! Imagine two copper cubes of equal size and mass. One of them has a has a temperature of 25 degrees Celsius while the other has a temperature of 75 degrees Celsius. Imagine further that these copper cubes are perfectly insulated from the surrounding world and that there is no heat transfer by convection or radiation. What will happen when we bring the two cubes into "perfect" physical contact?

Along the area of contact, the atoms of the 75-degree cube will vibrate faster than those of the 25-degree cube. Every now and then a 75-degree atom will "hit" a 25-degree atom and transfer its "kinetic energy" in the process, creating a 75-degree atom in the 25-degree cube and vice versa. Since this happens all along the area of contact, pretty soon we'll have an even mixture of 75-degree and 25-degree atoms wiggling around in these two "layers" of each cube. So on average, across all the atoms along the area of contact, we have a temperature of (25+75)/2.0 = 50.0 degrees.

What about the "next two layers" of atoms in each cube? They will in turn "exchange" equal amounts of 75-degree and 25-degree atoms with the contact layers, and so on. Eventually the average temperature of both cubes will be 50 degrees Celsius, and they will remain 50 degrees even if we separate them again.


General assignment requirements, style and submission details: