1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License as
4  * published by the Free Software Foundation; either version 2 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful, but
8  * WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOUSE. See the GNU
10  * General Public License for more details.
11  *
12  * You should have recieved a copy of the GNU General Public License
13  * along with this program; if not write to the Free Software
14  * Foundation, inc., 59 Temple Place, Suite 330, Boston MA 02111-1307
15  * USA
16  */
17 
18 package run;
19 
20 import java.util.*;
21 import java.io.*;
22 import java.nio.channels.*;
23 
24 
25 import run.readers.FembicReader;
26 
27 import jp.sync.*;
28 
29 /**
30  * Solver SMP
31  *
32  * @author Jonas Forssell, Yuriy Mikhaylovskiy
33  *
34  */
35 
36 
37 public class ModelSmp implements Runnable, ExceptionListener {
38 	private volatile double time,ttemp;
39 	private double timestep;
40 	private boolean autostep;
41 	private boolean failure_is_set = false;
42 	private int number_of_elements;
43     private int number_of_trackers;
44     private int number_of_nodes;
45     private int number_of_materials;
46     private int number_of_controls;
47     private int number_of_groups;
48     private int number_of_constraints;
49     private int number_of_loads;
50     private int nr_of_CPUs;
51     private String filename;
52     private Hashtable nodetable;
53     private RplVector nodelist;
54     private RplVector elementlist;
55     private RplVector trackerlist;
56     private RplVector materiallist;
57     private RplVector constraintlist;
58     private RplVector loadlist;
59     private Controlset controlset;
60     private int i;
61     private Element temporary_element;
62     private Tracker temporary_tracker;
63     private Constraint temporary_constraint;
64     private Node temporary_node;
65     private Writer resultwriter;
66     private TrackWriter trackwriter;
67     private Thread[] tsolve;
68     private Worker[] worker;
69     private Set exception_listeners;
70     private double timestep_error = Double.MAX_VALUE;
71 
72 
73 
74     /**
75      * ModelSmp constructor comment.
76      */
ModelSmp(int nr_of_CPUs, String fname)77     public ModelSmp(int nr_of_CPUs, String fname) {
78         super();
79         this.nr_of_CPUs = nr_of_CPUs;
80         exception_listeners = Collections.synchronizedSet(new HashSet());
81         this.filename = fname;
82     }
83 
84     /**
85      * Assemble Mass Matrix
86      */
assembleMassMatrix()87     public void assembleMassMatrix()
88         throws Exception
89     {
90         int i;
91         Node temp_node;
92         Element temp_element;
93         Constraint temp_constraint;
94 
95         // Loop elements
96         // Calculate element mass distribution and add to node
97         // Calculate element intertia
98         // Transform to global directions
99         // Add to node inertia matrix
100         // End loop
101         try {
102             System.out.println("Assembling Elements");
103 
104             for (i = 0; i < number_of_elements; i++) {
105                 temp_element = (Element) elementlist.elementAt(i);
106                 temp_element.assembleMassMatrix();
107             }
108         } catch (ArrayIndexOutOfBoundsException e) {
109             throw new ArrayIndexOutOfBoundsException(
110                 "\n* Error during Assembly phase - Terminating" + e
111             );
112         } catch (NullPointerException e) {
113             throw new NullPointerException(
114                 "\n* Error during Assembly phase of Element\n* This error could be the result of a missing (or wrong) parameter in the indata file \n* " +
115                 e
116             );
117         }
118 
119         // Loop nodes
120         // Calculate main inertias
121         // Keep largest I
122         // End loop
123         try {
124             System.out.println("Assembling Nodes");
125 
126             for (i = 0; i < nodelist.size(); i++) {
127                 temp_node = (Node) nodelist.elementAt(i);
128                 temp_node.determineMassMatrix();
129             }
130         } catch (ArrayIndexOutOfBoundsException e) {
131             throw new ArrayIndexOutOfBoundsException(
132                 "\n* Error during Assembly phase - Terminating" + e
133             );
134         } catch (NullPointerException e) {
135             throw new NullPointerException(
136                 "\n* Error during Assembly phase of Node \n* This error could be the result of a missing (or wrong) parameter in the indata file \n* " +
137                 e
138             );
139         }
140 
141         try {
142             System.out.println("Assembling Constraints");
143 
144             for (i = 0; i < number_of_constraints; i++) {
145                 temp_constraint = (Constraint) constraintlist.elementAt(i);
146                 temp_constraint.determineMassMatrix(nodelist);
147             }
148         } catch (ArrayIndexOutOfBoundsException e) {
149             throw new ArrayIndexOutOfBoundsException(
150                 "\n* Error during Assembly phase - Terminating" + e
151             );
152         } catch (NullPointerException e) {
153             throw new NullPointerException(
154                 "\n* Error during Assembly phase of Constraint \n* This error could be the result of a missing (or wrong) parameter in the indata file \n* " +
155                 e
156             );
157         }
158     }
159 
160     /**
161      * This method initializes the problem in the following steps:
162      * 1. Create a file object so that the indata file can be read.
163      * 2. Question the file object of all the variables etc that is required to set up all the
164      * memory variables etc correctly.
165      * 3. Set up the variables
166      * 4. Finished
167      *
168      * @param filename java.lang.String
169      */
initialize(String fname)170     public void initialize(String fname)
171         throws Exception
172     {
173         double frac, frac2;
174 
175         filename = new String(fname);
176 
177         // Create an indata file object that we can ask for the things we require
178         Reader indatafile = new FembicReader(filename);
179 
180         // Set number of elements, materials and nodes
181         number_of_elements = indatafile.numberOfElements();
182         number_of_trackers = indatafile.numberOfTrackers();
183         number_of_materials = indatafile.numberOfMaterials();
184         number_of_nodes = indatafile.numberOfNodes();
185         number_of_constraints = indatafile.numberOfConstraints();
186         number_of_loads = indatafile.numberOfLoads();
187         number_of_controls = indatafile.numberOfControls();
188         number_of_groups = indatafile.numberOfGroups();
189 
190         //Set up the arrays to handle the entries
191         elementlist = new RplVector(number_of_elements);
192         trackerlist = new RplVector(number_of_trackers);
193         materiallist = new RplVector(number_of_materials);
194         nodelist = new RplVector(number_of_nodes);
195         nodetable = new Hashtable(number_of_nodes);
196         constraintlist = new RplVector(number_of_constraints);
197         loadlist = new RplVector(number_of_loads);
198         controlset = new Controlset();
199         //grouplist = new RplVector(number_of_groups);
200 
201         try {
202             //Fill the constraintlist array
203             System.out.println("Reading Constraints");
204             indatafile.open();
205 
206             for (i = 0; i < number_of_constraints; i++) {
207                 constraintlist.addElement(
208                     indatafile.getNextConstraint(nodelist)
209                 );
210             }
211 
212             indatafile.close();
213             System.out.println("Filled constraintlist");
214 
215             //Fill the loadlist array
216             System.out.println("Reading Loads");
217             indatafile.open();
218 
219             for (i = 0; i < number_of_loads; i++) {
220                 loadlist.addElement(indatafile.getNextLoad(nodelist));
221             }
222 
223             indatafile.close();
224             System.out.println("Filled loadlist");
225 
226             //Fill the nodelist array
227             indatafile.open();
228             System.out.println("Reading Nodes");
229             frac2 = 0;
230 
231             for (i = 0; i < number_of_nodes; i++) {
232 
233                 temporary_node = indatafile.getNextNode(constraintlist, loadlist);
234 
235                 nodelist.addElement(temporary_node);
236                 nodetable.put(new Integer(temporary_node.getNumber()), temporary_node);
237 
238                 frac = i*10 / number_of_nodes;
239                 frac %= 10;
240 
241                 if (frac != frac2) {
242                     System.out.println("" + 10*frac + "% complete");
243                     frac2 = frac;
244                 }
245             }
246 
247             indatafile.close();
248             System.out.println("Filled nodelist");
249 
250             //Fill the materials array
251             indatafile.open();
252             System.out.println("Reading Materials");
253 
254             Material m;
255 
256             for (i = 0; i < number_of_materials; i++) {
257                 m = indatafile.getNextMaterial();
258 
259                 if (m.failure_strain_is_set || m.failure_stress_is_set) {
260                     failure_is_set = true;
261                 }
262 
263                 materiallist.addElement(m);
264             }
265 
266             indatafile.close();
267             System.out.println("Filled materiallist");
268 
269             //Fill the Elements array
270             indatafile.open();
271             System.out.println("Reading Elements");
272             frac2 = 0;
273 
274             for (i = 0; i < number_of_elements; i++) {
275                 elementlist.addElement(indatafile.getNextElement(materiallist, nodelist, loadlist, nodetable));
276 
277                 frac = i*10 / number_of_elements;
278                 frac %= 10;
279 
280                 if (frac != frac2) {
281                     System.out.println("" + 10*frac + "% complete");
282                     frac2 = frac;
283                 }
284             }
285 
286             indatafile.close();
287             System.out.println("Filled elementlist");
288 
289             //Fill the Trackers array
290             indatafile.open();
291             System.out.println("Reading Trackers");
292 
293             for (i = 0; i < number_of_trackers; i++) {
294                 trackerlist.addElement(
295                     indatafile.getNextTracker(nodelist, elementlist)
296                 );
297             }
298 
299             indatafile.close();
300             System.out.println("Filled trackerlist");
301 
302 
303             // Fill the grouplist array
304             /*
305              * Here, the grouplist could be filled.
306              */
307 
308 
309             //Get the controlset
310             indatafile.open();
311             System.out.println("Reading Controls");
312 
313             for (i = 0; i < number_of_controls; i++) {
314             	indatafile.getControlSet(controlset);
315             }
316 
317             indatafile.close();
318             System.out.println("Filled controlset");
319 
320             // Create an outdata file that will print the results in the format we wish
321             resultwriter = indatafile.getWriter(nodelist, elementlist, controlset, null);
322 
323             // Create a trackwriter that will print all trackresults in right format
324             trackwriter = indatafile.getTrackWriter(trackerlist, controlset, null);
325         } catch (java.text.ParseException e) {
326             // If we end up here, something is wrong in the indata file, reading the parameters
327             throw new java.text.ParseException("Parameter error in indata file \n" + e + " in line " +
328                 e.getErrorOffset(), e.getErrorOffset()
329             );
330         }
331 
332         //Initialize the writer
333         try {
334             resultwriter.initialize();
335         } catch (Exception e) {
336             throw new Exception("Initialization error of writer" + e,e);
337         }
338 
339         //Initialize the trackwriter
340         try {
341             trackwriter.initialize();
342         } catch (Exception e) {
343             throw new Exception("Initialization error of trackwriter" + e,e);
344         }
345 
346 
347     }
348 
349     /**
350      * Insert the method's description here. Creation date: (2001-08-20
351      * 22:03:57)
352      */
post()353     public void post() {
354     }
355 
356     /**
357      * This method prints the requested state of the solution to a file The
358      * file will be called the same name as the indatafile, but with an ending
359      * of *.res
360      */
print()361     private void print() {
362         System.out.println();
363         System.out.println();
364         System.out.println("time:" + time);
365         try {
366         resultwriter.write(filename, time);
367         trackwriter.write(time);
368         } catch (IOException ioe) {
369             System.out.println(ioe);
370             return;
371         }
372 
373     }
374 
375     /**
376      * Insert the method's description here. Creation date: (2001-08-20
377      * 22:03:07)
378      */
setInitialConditions()379     public void setInitialConditions() {
380         int i;
381         int j;
382         Node temp_node;
383         Node neighbour_node;
384         Element temp_element;
385         Tracker temp_tracker;
386         Constraint temp_constraint;
387         double total_mass;
388 
389 
390         // Initialize all the nodes
391         System.out.println("Initializing nodes");
392 
393         for (i = 0; i < nodelist.size(); i++) {
394             temp_node = (Node) nodelist.elementAt(i);
395             temp_node.setInitialConditions();
396         }
397 
398         /*
399          * Sort the nodes in ascending x-coordinate order.
400          */
401         System.out.println("Sorting nodes");
402 
403         Collections.sort(nodelist,new NodeComparator());
404 
405         /*
406          * Set up the neighbour pointers needed for contact algorithm
407          * Give each node a handle to it's neighbour
408          */
409         System.out.println("Setting up node neighbour handles");
410 
411         for (j = 0; j < nodelist.size(); j++) {
412             temp_node = (Node) nodelist.elementAt(j);
413 
414             if (j < (nodelist.size() - 1)) {
415                 temp_node.setRight_neighbour((Node) nodelist.elementAt(j + 1));
416             }
417 
418             if (j > 0) {
419                 temp_node.setLeft_neighbour((Node) nodelist.elementAt(j - 1));
420             }
421         }
422 
423 
424         // Assigning nodes to a CPU
425         System.out.println("Determining optimal model distribution for nodes");
426 
427        	// First get leftmost node
428        	temp_node = (Node) nodelist.firstElement();
429 
430        	while (temp_node.getLeft_neighbour() != null)
431        		temp_node = temp_node.getLeft_neighbour();
432 
433        	// Now, assign in increasing x-coordinate to CPU
434        	for (i = 0; i < nodelist.size(); i++) {
435             temp_node.setCpu_number(i*nr_of_CPUs/nodelist.size());
436        		temp_node = temp_node.getRight_neighbour();
437        	}
438 
439         // Initialize all the elements
440         System.out.println("Initializing elements");
441 
442         for (i = 0; i < number_of_elements; i++) {
443             temp_element = (Element) elementlist.elementAt(i);
444             temp_element.setInitialConditions();
445         }
446 
447         // Assign each element to a CPU
448         System.out.println("Assigning each element to a CPU");
449 
450         for (i = 0; i < number_of_elements; i++) {
451             temp_element = (Element) elementlist.elementAt(i);
452        		temp_element.determineCpu_number();
453         }
454 
455         // Initialize all the trackers
456         System.out.println("Initializing trackers");
457 
458         for (i = 0; i < number_of_trackers; i++) {
459             temp_tracker = (Tracker) trackerlist.elementAt(i);
460             temp_tracker.setInitialConditions();
461         }
462 
463         // Initialize all the constraints
464         System.out.println("Initializing constraints");
465 
466         for (i = 0; i < number_of_constraints; i++) {
467             temp_constraint = (Constraint) constraintlist.elementAt(i);
468             temp_constraint.setInitialConditions();
469         }
470 
471         // Initialize the controlset
472         controlset.setInitialConditions();
473 
474         // Now, if autostep is used, loop through all elements and determine the smallest timestep
475         System.out.println("Determining smallest timestep size");
476 
477         if (controlset.getTimestep(0) == 0) {
478             timestep = 1E10;
479             autostep = true;
480 
481             for (i = 0; i < number_of_elements; i++) {
482                 timestep = ((Element) elementlist.elementAt(i)).checkTimestep(timestep);
483             }
484         } else {
485             timestep = controlset.getTimestep(0);
486             autostep = false;
487         }
488 
489         System.out.println("Determined timestep: " + timestep);
490         // Sum up total model mass and print
491         System.out.println("Calculating total model mass");
492         total_mass = 0;
493 
494         for (i = 0; i < nodelist.size(); i++) {
495             temp_node = (Node) nodelist.elementAt(i);
496             total_mass += temp_node.getMass();
497         }
498 
499         System.out.println("Total model mass = " + total_mass);
500 
501     }
502 
503     /**
504      * This is the main loop of the program. Here, the solution is conducted.
505      */
solve()506     public void solve() throws InterruptedException {
507         long time_info;
508         long time_info_tmp;
509         long time_remained;
510         int time_h;
511         int time_m;
512         int time_s;
513         String time_str;
514         final Barrier barrier;
515         boolean autosave = false;
516 
517         time_info = new Date().getTime();
518         ttemp = 1E10;
519 
520         // Set up an array of processes to distribute on each CPU
521         tsolve = new Thread[nr_of_CPUs];
522         worker = new Worker[nr_of_CPUs];
523         int worker_element[] = new int[nr_of_CPUs];
524         int worker_node[] = new int[nr_of_CPUs];
525         barrier = BarrierFactory.createBarrier(nr_of_CPUs+1);
526 
527         // These threads represent a subset of the work done in the main thread.
528         // Over time, most of the processes will be parallel
529 
530         time = controlset.getStarttime();
531 
532         readAutoSave();
533         readAutoSaveError();
534 
535     	//Create workers and threads
536     	for(i=0; i<nr_of_CPUs; i++) {
537             worker[i] = new Worker(barrier,time,timestep,autostep);
538             worker[i].addExceptionListener(this);
539             tsolve[i] = new Thread(worker[i]);
540             worker_element[i] = 0;
541             worker_node[i] = 0;
542         }
543 
544     	System.out.println("Distributing the model on " + nr_of_CPUs + " CPU:s");
545    		for (int i=0; i<elementlist.size(); i++) {
546    			temporary_element = (Element)elementlist.elementAt(i);
547    			worker[temporary_element.getCpu_number()].addElement(temporary_element);
548    			worker_element[temporary_element.getCpu_number()]++;
549         }
550 
551    		for (int i=0; i<nodelist.size(); i++) {
552 			temporary_node = (Node)nodelist.elementAt(i);
553 			worker[temporary_node.getCpu_number()].addNode(temporary_node);
554 			worker_node[temporary_node.getCpu_number()]++;
555     	}
556    		for(i=0; i<nr_of_CPUs; i++) {
557         	System.out.println("CPU "+i+" Nodes: "+worker_node[i]+" \tElements: "+worker_element[i]);
558         }
559 
560     	// Start all threads
561         for(i=0; i<nr_of_CPUs; i++) {
562         	tsolve[i].setPriority(Thread.MIN_PRIORITY);
563         	tsolve[i].start();
564         }
565 
566 
567 
568         // This is the main loop which will run in tandem with the other threads;
569         for(time = time; time <= controlset.getEndtime(); time += timestep){
570 
571         	// Set next loop time and timestep for the workers
572         	for (i = 0; i < nr_of_CPUs; i++) {
573         		worker[i].setTime(time);
574         		worker[i].setTimestep(timestep);
575         		worker[i].setAutostep(autostep);
576         	}
577 
578         	barrier.sync();
579 
580         	// *********** Worker ***************
581         	// 	Loop elements
582         	// **********************************
583 
584         	barrier.sync();
585 
586         	// Remove failed elements
587         	if (failure_is_set) {
588         		for (i = 0; i < number_of_elements; i++) {
589         			temporary_element = (Element) elementlist.elementAt(i);
590         			if (!temporary_element.isDeActivated()) {
591         			    temporary_element.checkIfFailed();
592         			    if (temporary_element.hasFailed())
593         			        temporary_element.deActivate();
594         			}
595         		}
596         	}
597 
598 
599         	// Loop constraints
600         	for (i = 0; i < number_of_constraints; i++) {
601         		temporary_constraint = (Constraint) constraintlist.elementAt(i);
602         		temporary_constraint.update();
603         	}
604 
605         	// Loop Nodes
606         	for (i = 0; i < nodelist.size(); i++) {
607         	    // Get a node from the array
608         	    temporary_node = (Node) nodelist.elementAt(i);
609 
610         	    if (!temporary_node.isDeActivated()) {
611         	        // Update acceleration, velocity and position of node (supply timestep because it is needed in the calculations)
612         	        // Note, the update includes application of boundary conditions.
613         	        // The update also includes addition of any external forces from boundary conditions.
614         	        temporary_node.calculateNewPosition(timestep, time);
615 
616         	        // Check for neighbours (needed for contact algorithm)
617         	        temporary_node.checkNeighbours();
618         	    }
619         	    // End loop
620         	}
621 
622         	// Loop Trackers
623         	for (i = 0; i < number_of_trackers; i++) {
624         		// Get a tracker from the array
625         		temporary_tracker = (Tracker) trackerlist.elementAt(i);
626 
627         		// Collect the data
628         		temporary_tracker.collectData();
629 
630         		// Perform needed calculations
631         		temporary_tracker.calculate();
632         	}
633 
634 
635         	// Update timestep
636         	if (controlset.getTimestep(time) == 0) {
637         		for (i = 0; i < nr_of_CPUs; i++) {
638         			ttemp = Math.min(ttemp,worker[i].getTtemp());
639         		}
640         		timestep = ttemp;
641         		ttemp = 1E10;
642         		autostep = true;
643         	} else {
644         		timestep = controlset.getTimestep(time);
645         		if(timestep>timestep_error) timestep = timestep_error;
646         		autostep = false;
647         	}
648 
649         	// Check if it is time to print something
650         	if (controlset.timeToPrint(time)) {
651         		System.out.println();
652         		System.out.println();
653         		time_info_tmp = new Date().getTime();
654         		time_remained = (((time_info_tmp - time_info) * ((int) ((controlset.getEndtime() -
655     				time) / controlset.getPrintstep()))) / 1000);
656         		time_h = (int) (time_remained / 3600);
657         		time_m = (int) ((time_remained / 60) - (time_h * 60));
658         		time_s = (int) (time_remained -
659     				(((int) (time_remained / 60)) * 60));
660         		time_str = "";
661 
662         		if (time_h < 10) {
663         			time_str += ("0" + time_h);
664         		} else {
665         			time_str += time_h;
666         		}
667 
668         		if (time_m < 10) {
669         			time_str += (":0" + time_m);
670         		} else {
671         			time_str += (":" + time_m);
672         		}
673 
674         		if (time_s < 10) {
675         			time_str += (":0" + time_s);
676         		} else {
677         			time_str += (":" + time_s);
678         		}
679 
680         		System.out.println("Time: " + time + "\tRemaining time (hh:mm:ss) " + time_str);
681         		time_info = time_info_tmp;
682         		try {
683         			resultwriter.write(filename, time);
684         			autosave = true;
685         		} catch (IOException ioe) {
686         			System.out.println(ioe);
687         			return;
688         		}
689 
690         	}
691 
692         	// Check if it is time to print something on the trackers
693         	if (controlset.timeToPrintTracker(time)) {
694         		trackwriter.write(time);
695         	}
696 
697         	barrier.sync();
698 
699         	// *********** Worker ***************
700         	// Loop Nodes again to clear forces
701         	// **********************************
702 
703         	barrier.sync();
704 
705         	if (autosave){
706         		writeAutoSave();
707         		autosave = false;
708         	}
709 
710         }
711 
712         // Solution is finished correctly. Finish off the workers
713 		for (i = 0; i < nr_of_CPUs; i++)
714 			tsolve[i].interrupt();
715 
716 		// and end this solution
717         this.post();
718     }
719 
720 
721     /**
722      * This is where we end up when a serious exception has occurred in the worker threads
723      *
724      */
exceptionOccurred(Exception e, Object o)725     public void exceptionOccurred(Exception e, Object o){
726 
727         stopThreads();
728         // Pass this error on to the GUI
729         sendException(e);
730     }
731 
732     /**
733      * This method sends an exception to registred listeners.
734      * This is needed since exception migrates normally only to the run() method and not outside.
735      *
736      * @param e The exception to send
737      */
sendException(Exception e)738     private void sendException(Exception e) {
739        if (exception_listeners.size() == 0) {
740            e.printStackTrace();
741            return;
742        }
743 
744        Iterator iter = exception_listeners.iterator();
745 
746        while (iter.hasNext()) {
747            ExceptionListener l = (ExceptionListener) iter.next();
748            l.exceptionOccurred(e,this);
749        }
750        if(!(e instanceof InterruptedException)) writeAutoSaveError();
751     }
752 
753 
stopThreads()754     public void stopThreads() {
755         for (int i=0 ; i < nr_of_CPUs; i++)
756             if (tsolve != null && tsolve[i] != null)
757                 tsolve[i].interrupt();
758 
759         for (int i=0 ; i < nr_of_CPUs; i++) {
760         	try {
761         		if (tsolve != null && tsolve[i] != null)
762         			tsolve[i].join();
763         	} catch (InterruptedException e) { }
764         }
765     }
766 
767     /**
768      * Add exception listener to the object
769      *
770      * @param l The listener to add
771      */
addExceptionListener(ExceptionListener l)772     public void addExceptionListener(ExceptionListener l) {
773         exception_listeners.add(l);
774     }
775 
776 
run()777     public void run() {
778         long stime;
779 
780         System.out.println("Processing file: " + filename);
781         System.out.println("*** Initializing ***");
782 
783         try {
784             initialize(filename);
785 
786             if (Thread.currentThread().isInterrupted())
787                 throw new InterruptedException();
788 
789             // Assemble the mass matrix
790             System.out.println("*** Assembling the Mass Matrix ***");
791             assembleMassMatrix();
792 
793             if (Thread.currentThread().isInterrupted())
794                 throw new InterruptedException();
795 
796             // Set up the prerequisites
797             System.out.println("*** Setting Initial Conditions ***");
798             setInitialConditions();
799 
800             if (Thread.currentThread().isInterrupted())
801                 throw new InterruptedException();
802 
803             // Solve the problem
804             stime = System.currentTimeMillis();
805             System.out.println("*** Initiating Solver ***");
806 
807             solve();
808 
809 
810         } catch (Exception e) {
811             stopThreads();
812             sendException(e);   // Notify GUI
813             return;
814 
815         }
816 
817         System.out.println("Solving took " + (System.currentTimeMillis() - stime) + " ms");
818 
819         // Post the results and clean up
820         post();
821 
822         //Solution has ended successfully
823     }
824 
825     // Auto save
writeAutoSave()826     public void writeAutoSave(){
827     	if(controlset.getRestoreSaveStatus()==Controlset.RESTORE_SAVE_OFF) return;
828     	try{
829     		ObjectOutputStream aout = new ObjectOutputStream(new FileOutputStream(filename+".autosave"));
830     		writeObject(aout);
831     		aout.flush();
832     		aout.close();
833     		if(controlset.getRestoreSaveStatus()==Controlset.RESTORE_SAVE_PREVIOUS){
834     			System.out.println("Auto Save Time: " + time + " ... ok");
835     			System.out.println(new Date() + "\n");
836     			return;
837     		}else{
838     			FileChannel fain = new FileInputStream(filename+".autosave").getChannel();
839     			FileChannel faout = new FileOutputStream(filename+".autosave."+time).getChannel();
840     			fain.transferTo(0, fain.size(), faout);
841     			fain.close();
842     			faout.close();
843     			FileChannel frin = new FileInputStream(filename+".flavia.res").getChannel();
844     			FileChannel frout = new FileOutputStream(filename+".flavia.res."+time).getChannel();
845     			frin.transferTo(0, frin.size(), frout);
846     			frin.close();
847     			frout.close();
848     			for (i = 0; i < number_of_trackers; i++) {
849     				temporary_tracker = (Tracker) trackerlist.elementAt(i);
850     				FileChannel ftin = new FileInputStream(temporary_tracker.filename).getChannel();
851     				FileChannel ftout = new FileOutputStream(temporary_tracker.filename+"."+time).getChannel();
852     				ftin.transferTo(0, ftin.size(), ftout);
853     				ftin.close();
854     				ftout.close();
855     			}
856     			System.out.println("Auto Save Time: " + time + " ... ok");
857     			System.out.println(new Date() + "\n");
858     		}
859     	} catch (Exception e) {e.printStackTrace();	}
860     }
861 
readAutoSave()862     public void readAutoSave(){
863     	if(controlset.getRestoreSaveStatus()==Controlset.RESTORE_SAVE_OFF
864     		|| ! new File(filename+".autosave").exists()
865     	) return;
866     	try{
867     		ObjectInputStream ain = new ObjectInputStream(new FileInputStream(filename+".autosave"));
868     		readObject(ain);
869     		ain.close();
870     		System.out.println("Found saved result for Time: " + time + "\tTime step: "+timestep);
871     	} catch (Exception e) {if(! (e instanceof FileNotFoundException)) e.printStackTrace();	}
872     }
873 
writeObject(java.io.ObjectOutputStream out)874     private void writeObject(java.io.ObjectOutputStream out) throws IOException{
875     	out.writeDouble(time);
876     	out.writeDouble(ttemp);
877     	out.writeDouble(timestep);
878     	out.writeBoolean(autostep);
879     	out.writeBoolean(failure_is_set);
880     	out.writeInt(number_of_elements);
881     	out.writeInt(number_of_trackers);
882     	out.writeInt(number_of_nodes);
883     	out.writeInt(number_of_materials);
884     	out.writeInt(number_of_controls);
885     	out.writeInt(number_of_groups);
886     	out.writeInt(number_of_constraints);
887     	out.writeInt(number_of_loads);
888     	out.writeInt(nr_of_CPUs);
889     	out.writeObject(filename);
890     	out.writeObject(nodetable);
891     	out.writeObject(nodelist);
892     	out.writeObject(elementlist);
893     	out.writeObject(trackerlist);
894     	out.writeObject(materiallist);
895     	out.writeObject(constraintlist);
896     	out.writeObject(loadlist);
897     	out.writeObject(controlset);
898     	out.writeObject(resultwriter);
899     	out.writeObject(trackwriter);
900     }
901 
readObject(java.io.ObjectInputStream in)902     private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
903     	time = in.readDouble();
904     	ttemp = in.readDouble();
905     	timestep = in.readDouble();
906     	autostep = in.readBoolean();
907     	failure_is_set = in.readBoolean();
908     	number_of_elements = in.readInt();
909         number_of_trackers = in.readInt();
910         number_of_nodes = in.readInt();
911         number_of_materials = in.readInt();
912         number_of_controls = in.readInt();
913         number_of_groups = in.readInt();
914         number_of_constraints = in.readInt();
915         number_of_loads = in.readInt();
916         nr_of_CPUs = in.readInt();
917         filename = (String) in.readObject();
918         nodetable = (Hashtable) in.readObject();
919         nodelist = (RplVector) in.readObject();
920         elementlist = (RplVector) in.readObject();
921         trackerlist = (RplVector) in.readObject();
922         materiallist = (RplVector) in.readObject();
923         constraintlist = (RplVector) in.readObject();
924         loadlist = (RplVector) in.readObject();
925         controlset = (Controlset) in.readObject();
926         resultwriter = (Writer) in.readObject();
927         trackwriter = (TrackWriter) in.readObject();
928     }
929 
930     /*
931      * At occurrence of an error calculation stops.
932      * In a file error time, an error step are saved.
933      * At restart of model time step decreases twice
934      * ( timestep = timestep_error / 2 ).
935      * So there is each time at model start.
936      * It allows to define a step correctly.
937      *
938      * ��� ������������� ������ ������ ���������������.
939      * � ���� ��������� ����� ������, ��� ������.
940      * ��� ��������� ������� ������ ��� ������� ����������� � ��� ����
941      * ( timestep = timestep_error / 2 ).
942      * ��� ���������� ������ ��� ��� ������� ������.
943      * ��� ��������� ��������� ���������� ���.
944      */
945 
writeAutoSaveError()946     public void writeAutoSaveError(){
947     	if(controlset.getRestoreSaveStatus()==Controlset.RESTORE_SAVE_OFF) return;
948     	try{
949     		String info = " At occurrence of an error calculation stops."
950     			+"\n In a file error time, an error step are saved."
951     			+"\n At restart of model time step decreases twice"
952     			+"\n ( timestep = timestep_error / 2 )."
953     			+"\n So there is each time at model start."
954     			+"\n It allows to define a step correctly.\n";
955     		Properties prop = new Properties();
956     		prop.setProperty("Time", time+"");
957     		prop.setProperty("TimeStep", timestep+"");
958     		prop.store(new FileOutputStream(filename+".error"), info);
959     	} catch (Exception e) {e.printStackTrace();	}
960     }
961 
readAutoSaveError()962     public void readAutoSaveError(){
963     	if(controlset.getRestoreSaveStatus()==Controlset.RESTORE_SAVE_OFF
964     		|| ! new File(filename+".error").exists()
965     	) return;
966     	try{
967     		Properties prop = new Properties();
968     		prop.load(new FileInputStream(filename+".error"));
969     		timestep_error = Double.parseDouble(prop.getProperty("TimeStep"));
970     		System.out.println("Found saved error for Time: " + time + "\tTime step: "+timestep_error);
971         	timestep_error /= 2.0d;
972         	if(timestep>timestep_error) timestep = timestep_error;
973         	System.out.println("Changed time step: "+timestep_error);
974     	} catch (Exception e) {if(! (e instanceof FileNotFoundException)) e.printStackTrace();	}
975     }
976 
977 }
978 
979