// -*- C++ -*-
// $RCSfile: infodashboard.C,v $
// $Revision: 1.7 $
// $Author: langer $
// $Date: 2000/11/20 21:11:08 $
/* This software was produced by NIST, an agency of the U.S. government,
* and by statute is not subject to copyright in the United States.
* Recipients of this software assume all responsibilities associated
* with its operation, modification and maintenance. However, to
* facilitate maintenance we ask that before distributing modifed
* versions of this software, you first contact the authors at
* oof_manager@ctcms.nist.gov.
*/
#include "colorutils.h"
#include "create_form_drawer.h"
#include "delete_fl_group.h"
#include "element.h"
#include "eulerangle.h"
#include "formdrawer.h"
#include "graphics.h"
#include "grid.h"
#include "infodashboard.h"
#include "menuDef.h"
#include "mouseclick.h"
#include "mvmult.h"
#include "node.h"
#include "parameters.h"
#include "symeig3.h"
#include <iomanip.h>
#include <math.h>
TrueFalse InfoDashboard::infoflag_mouseposition_dflt(0);
InfoDashboard::InfoDashboard(const CharString &nm, Drawer *drwr)
: Dashboard(nm, drwr, RB_NONE),
infoflag_mouseposition(infoflag_mouseposition_dflt)
{
// mouse position button is initialized in set_infobuttons().
AddVariable(&menu, "mouseposition", "mouse position", infoflag_mouseposition,
set_infobuttons_cmd);
}
InfoDashboard::~InfoDashboard() {
menu.RemoveOption("mouseposition");
}
void ElementInfo::show() {
fl_show_object(elementinfo);
setcursor(*infocursor);
}
void ElementInfo::hide() {
fl_hide_object(elementinfo);
unsetcursor();
}
void InfoDashboard::set_info_mouseposition() {
infoflag_mouseposition = infoflag_mouseposition_dflt =
fl_get_button(info_mouseposition);
garcon()->log(menucommand() + "mouseposition="
+ to_charstring(infoflag_mouseposition));
}
void FDCB_info_mouseposition(FL_OBJECT*, long ptr) {
((InfoDashboard*) ptr)->set_info_mouseposition();
}
void InfoDashboard::set_infobuttons_cmd(const CharString&) {
((InfoDashboard*) get_dashboard())->set_infobuttons();
}
//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//
TrueFalse ElementInfo::infoflag_elementtype_dflt(1);
TrueFalse ElementInfo::infoflag_nodeindices_dflt(0);
TrueFalse ElementInfo::infoflag_elementindex_dflt(0);
TrueFalse ElementInfo::infoflag_intrinsicgray_dflt(0);
TrueFalse ElementInfo::infoflag_elementparams_dflt(0);
TrueFalse ElementInfo::infoflag_stress_dflt(0);
TrueFalse ElementInfo::infoflag_strain_dflt(0);
TrueFalse ElementInfo::infoflag_components_dflt(1);
TrueFalse ElementInfo::infoflag_invariants_dflt(0);
TrueFalse ElementInfo::infoflag_eigenvalues_dflt(0);
TrueFalse ElementInfo::infoflag_energydensity_dflt(0);
#ifdef THERMAL
TrueFalse ElementInfo::infoflag_heatflux_dflt(0);
TrueFalse ElementInfo::infoflag_tempgradient_dflt(0);
TrueFalse ElementInfo::infoflag_temperature_dflt(0);
#endif // THERMAL
ElementInfo::ElementInfo(Drawer *drwr)
: InfoDashboard("Element Info", drwr),
infoflag_elementtype(infoflag_elementtype_dflt),
infoflag_nodeindices(infoflag_nodeindices_dflt),
infoflag_elementindex(infoflag_elementindex_dflt),
infoflag_intrinsicgray(infoflag_intrinsicgray_dflt),
infoflag_elementparams(infoflag_elementparams_dflt),
infoflag_stress(infoflag_stress_dflt),
infoflag_strain(infoflag_strain_dflt),
infoflag_components(infoflag_components_dflt),
infoflag_invariants(infoflag_invariants_dflt),
infoflag_eigenvalues(infoflag_eigenvalues_dflt),
infoflag_energydensity(infoflag_energydensity_dflt)
#ifdef THERMAL
,
infoflag_heatflux(infoflag_heatflux_dflt),
infoflag_tempgradient(infoflag_tempgradient_dflt),
infoflag_temperature(infoflag_temperature_dflt)
#endif // THERMAL
{
create_form_elementinfo(this);
set_infobuttons();
AddVariable(&menu, "elementtype", "element type", infoflag_elementtype,
set_infobuttons_cmd);
AddVariable(&menu, "nodeindices", "node indices", infoflag_nodeindices,
set_infobuttons_cmd);
AddVariable(&menu, "elementindex", "element index", infoflag_elementindex,
set_infobuttons_cmd);
AddVariable(&menu, "gray", "intrinsic gray", infoflag_intrinsicgray,
set_infobuttons_cmd);
AddVariable(&menu, "params", "element parameters", infoflag_elementparams,
set_infobuttons_cmd);
AddVariable(&menu, "stress", "stress", infoflag_stress, set_infobuttons_cmd);
AddVariable(&menu, "strain", "strain", infoflag_strain, set_infobuttons_cmd);
AddVariable(&menu, "components", "tensor components", infoflag_components,
set_infobuttons_cmd);
AddVariable(&menu, "invariants", "tensor invariants", infoflag_invariants,
set_infobuttons_cmd);
AddVariable(&menu, "eigenvalues", "eigenvalues", infoflag_eigenvalues,
set_infobuttons_cmd);
AddVariable(&menu, "energydensity", "energy density", infoflag_energydensity,
set_infobuttons_cmd);
#ifdef THERMAL
AddVariable(&menu, "heatflux", "heat flux", infoflag_heatflux,
set_infobuttons_cmd);
AddVariable(&menu, "tempgradient", "temperature gradient",
infoflag_tempgradient, set_infobuttons_cmd);
AddVariable(&menu, "temperature", "temperature", infoflag_temperature,
set_infobuttons_cmd);
#endif // THERMAL
}
ElementInfo::~ElementInfo() {
hide();
delete_fl_group(elementinfo);
/*
fl_delete_object(elementinfo);
fl_free_object(info_mouseposition);
fl_free_object(infoframe1);
fl_free_object(elementinfotext);
fl_free_object(info_elementtype);
fl_free_object(info_nodeindices);
fl_free_object(info_intrinsicgray);
fl_free_object(info_elementparams);
fl_free_object(info_stress);
fl_free_object(info_strain);
fl_free_object(info_11);
fl_free_object(info_22);
fl_free_object(info_12);
fl_free_object(info_inv1);
fl_free_object(info_inv2);
fl_free_object(info_eigenvalues);
fl_free_object(elementinfo);
*/
menu.RemoveOption("elementtype");
menu.RemoveOption("nodeindices");
menu.RemoveOption("elementindex");
menu.RemoveOption("gray");
menu.RemoveOption("params");
menu.RemoveOption("stress");
menu.RemoveOption("strain");
menu.RemoveOption("components");
menu.RemoveOption("invariants");
menu.RemoveOption("eigenvalues");
menu.RemoveOption("energydensity");
#ifdef THERMAL
menu.RemoveOption("heatflux");
menu.RemoveOption("tempgradient");
menu.RemoveOption("temperature");
#endif // THERMAL
}
void ElementInfo::set_infobuttons() const {
fl_set_button(info_mouseposition, infoflag_mouseposition);
fl_set_button(info_elementtype, infoflag_elementtype);
fl_set_button(info_elementindex, infoflag_elementindex);
fl_set_button(info_nodeindices, infoflag_nodeindices);
fl_set_button(info_intrinsicgray, infoflag_intrinsicgray);
fl_set_button(info_elementparams, infoflag_elementparams);
fl_set_button(info_stress, infoflag_stress);
fl_set_button(info_strain, infoflag_strain);
fl_set_button(info_components, infoflag_components);
fl_set_button(info_invariants, infoflag_invariants);
fl_set_button(info_eigenvalues, infoflag_eigenvalues);
fl_set_button(info_energydensity, infoflag_energydensity);
#ifdef THERMAL
fl_set_button(info_heatflux, infoflag_heatflux);
fl_set_button(info_tempgradient, infoflag_tempgradient);
fl_set_button(info_temperature, infoflag_temperature);
#endif // THERMAL
}
void ElementInfo::set_info_elementtype() {
infoflag_elementtype = infoflag_elementtype_dflt =
fl_get_button(info_elementtype);
garcon()->log(menucommand() + "elementtype=" +
to_charstring(infoflag_elementtype));
}
void FDCB_info_elementtype(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_elementtype();
}
void ElementInfo::set_info_nodeindices() {
infoflag_nodeindices = infoflag_nodeindices_dflt =
fl_get_button(info_nodeindices);
garcon()->log(menucommand() + "nodeindices=" +
to_charstring(infoflag_nodeindices));
}
void FDCB_info_nodeindices(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_nodeindices();
}
void ElementInfo::set_info_elementindex() {
infoflag_elementindex = infoflag_elementindex_dflt =
fl_get_button(info_elementindex);
garcon()->log(menucommand() + "elementindex=" +
to_charstring(infoflag_elementindex));
}
void FDCB_info_elementindex(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_elementindex();
}
void ElementInfo::set_info_intrinsicgray() {
infoflag_intrinsicgray = infoflag_intrinsicgray_dflt =
fl_get_button(info_intrinsicgray);
garcon()->log(menucommand() + "gray="
+ to_charstring(infoflag_intrinsicgray));
}
void FDCB_info_intrinsicgray(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_intrinsicgray();
}
void ElementInfo::set_info_elementparams() {
infoflag_elementparams = infoflag_elementparams_dflt =
fl_get_button(info_elementparams);
garcon()->log(menucommand() + "params="
+ to_charstring(infoflag_elementparams));
}
void FDCB_info_elementparams(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_elementparams();
}
void ElementInfo::set_info_stress() {
infoflag_stress = infoflag_stress_dflt =
fl_get_button(info_stress);
garcon()->log(menucommand() + "stress=" + to_charstring(infoflag_stress));
}
void FDCB_info_stress(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_stress();
}
void ElementInfo::set_info_strain() {
infoflag_strain = infoflag_strain_dflt =
fl_get_button(info_strain);
garcon()->log(menucommand() + "strain=" + to_charstring(infoflag_strain));
}
void FDCB_info_strain(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_strain();
}
void ElementInfo::set_info_components() {
infoflag_components = infoflag_components_dflt
= fl_get_button(info_components);
garcon()->log(menucommand() + "components=" +
to_charstring(infoflag_components));
}
void FDCB_info_components(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_components();
}
void ElementInfo::set_info_invariants() {
infoflag_invariants = infoflag_invariants_dflt
= fl_get_button(info_invariants);
garcon()->log(menucommand() + "invariants=" +
to_charstring(infoflag_invariants));
}
void FDCB_info_invariants(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_invariants();
}
void ElementInfo::set_info_eigenvalues() {
infoflag_eigenvalues = infoflag_eigenvalues_dflt =
fl_get_button(info_eigenvalues);
garcon()->log(menucommand() + "eigenvalues=" +
to_charstring(infoflag_eigenvalues));
}
void FDCB_info_eigenvalues(FL_OBJECT *, long ptr) {
((ElementInfo*) ptr)->set_info_eigenvalues();
}
void ElementInfo::set_info_energydensity() {
infoflag_energydensity = infoflag_energydensity_dflt =
fl_get_button(info_energydensity);
garcon()->log(menucommand() + "energydensity=" +
to_charstring(infoflag_energydensity));
}
void FDCB_info_energydensity(FL_OBJECT*, long ptr) {
((ElementInfo*) ptr)->set_info_energydensity();
}
#ifdef THERMAL
void ElementInfo::set_info_heatflux() {
infoflag_heatflux = infoflag_heatflux_dflt =
fl_get_button(info_heatflux);
garcon()->log(menucommand() + "heatflux=" +
to_charstring(infoflag_heatflux));
}
void FDCB_info_heatflux(FL_OBJECT*, long ptr) {
((ElementInfo*) ptr)->set_info_heatflux();
}
void ElementInfo::set_info_tempgradient() {
infoflag_tempgradient = infoflag_tempgradient_dflt =
fl_get_button(info_tempgradient);
garcon()->log(menucommand() + "tempgradient=" +
to_charstring(infoflag_tempgradient));
}
void FDCB_info_tempgradient(FL_OBJECT*, long ptr) {
((ElementInfo*) ptr)->set_info_tempgradient();
}
void ElementInfo::set_info_temperature() {
infoflag_temperature = infoflag_temperature_dflt =
fl_get_button(info_temperature);
garcon()->log(menucommand() + "temperature=" +
to_charstring(infoflag_temperature));
}
void FDCB_info_temperature(FL_OBJECT*, long ptr) {
((ElementInfo*) ptr)->set_info_temperature();
}
#endif // THERMAL
void ElementInfo::clickhandler(const MouseClick &click) {
if(!gridinit()) return;
garcon()->msout << "-----------" << endl;
if(infoflag_mouseposition)
garcon()->msout << " mouse at x=" << click.coord.x
<< " y=" << click.coord.y << endl;
Element *e = grid->findElement(click.coord);
if(!e || (e->isempty() && !drawer->showingempties())) return;
if(infoflag_elementtype)
garcon()->msout << " type: " << e->tag() << endl;
if(infoflag_elementindex)
garcon()->msout << " index: " << e->index << endl;
if(infoflag_nodeindices) {
garcon()->msout << " nodes: ";
for(int i=0; i<e->corner.capacity(); i++) {
garcon()->msout << " " << e->corner[i]->index;
}
garcon()->msout << endl;
}
if(infoflag_intrinsicgray)
garcon()->msout << " gray: " << e->intrinsic_gray << endl;
if(infoflag_elementparams)
garcon()->msout << " params:" << e->parameters() << endl;
if(infoflag_stress) {
garcon()->msout << " stress:" << endl;
infostressstrain(e->stresstensor());
}
if(infoflag_strain) {
garcon()->msout << " strain:" << endl;
infostressstrain(e->total_straintensor());
}
if(infoflag_energydensity)
garcon()->msout << " energy density: " << e->elastic_energy() << endl;
#ifdef THERMAL
if(infoflag_temperature)
garcon()->msout << " temperature: " << e->average_T() << endl;
if(infoflag_tempgradient)
garcon()->msout << "grad temperature: " << e->gradient_temperature_field()
<< endl;
if(infoflag_heatflux)
garcon()->msout << " heat flux: " << e->heat_flux_field() << endl;
#endif // THERMAL
}
void ElementInfo::infostressstrain(const StrainStress &str) const {
if(infoflag_components)
str.fancy_output(garcon()->msout," ") << endl;
if(infoflag_invariants) {
garcon()->msout << " invariant 1: " << str.invariant1() << endl;
garcon()->msout << " invariant 2: " << str.invariant2() << endl;
garcon()->msout << " invariant 3: " << str.invariant3() << endl;
}
if(infoflag_eigenvalues) {
EigenVector eig1, eig2, eig3;
eigensystem(str, eig1, eig2, eig3);
garcon()->msout << " eigenvalue orientation" << endl
<< setw(13) << eig1.eigenvalue << " "
<< eig1.orientation() << endl
<< setw(13) << eig2.eigenvalue << " "
<< eig2.orientation() << endl
<< setw(13) << eig3.eigenvalue << " "
<< eig3.orientation() << endl;
// garcon()->msout << " eigenvectors & eigenvalues: " << endl
// << eig1 << endl << eig2 << endl << eig3 << endl;
// MV_Vector_double test(3);
// test[0] = eig1.eigenvector[0];
// test[1] = eig1.eigenvector[1];
// test[2] = eig1.eigenvector[2];
// garcon()->msout << MV_ColMat_double(eig1.orientation())*test << endl;
// garcon()->msout << trans_mult(MV_ColMat_double(eig1.orientation()),test) << endl;
// garcon()->msout << str.transform(eig1.orientation()) << endl;
// garcon()->msout << str.transform(eig2.orientation()) << endl;
// garcon()->msout << str.transform(eig3.orientation()) << endl;
}
}
//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//-\\-//
TrueFalse NodeInfo::infoflag_nodetype_dflt(1);
TrueFalse NodeInfo::infoflag_nodeindex_dflt(0);
TrueFalse NodeInfo::infoflag_nodeposition_dflt(1);
TrueFalse NodeInfo::infoflag_nodedisplacement_dflt(0);
TrueFalse NodeInfo::infoflag_nodeoriginalpos_dflt(0);
TrueFalse NodeInfo::infoflag_nodeforce_dflt(0);
#ifdef THERMAL
TrueFalse NodeInfo::infoflag_nodetemperature_dflt(0);
#endif // THERMAL
NodeInfo::NodeInfo(Drawer *drwr)
: InfoDashboard("Node Info", drwr),
infoflag_nodetype(infoflag_nodetype_dflt),
infoflag_nodeindex(infoflag_nodeindex_dflt),
infoflag_nodeposition(infoflag_nodeposition_dflt),
infoflag_nodedisplacement(infoflag_nodedisplacement_dflt),
infoflag_nodeoriginalpos(infoflag_nodeoriginalpos_dflt),
infoflag_nodeforce(infoflag_nodeforce_dflt)
#ifdef THERMAL
,
infoflag_nodetemperature(infoflag_nodetemperature_dflt)
#endif // THERMAL
{
create_form_nodeinfo(this);
set_infobuttons();
AddVariable(&menu, "nodetype", "node type", infoflag_nodetype,
set_infobuttons_cmd);
AddVariable(&menu, "nodeindex", "node index", infoflag_nodeindex,
set_infobuttons_cmd);
AddVariable(&menu, "position", "node position", infoflag_nodeposition,
set_infobuttons_cmd);
AddVariable(&menu, "displacement", "node displacement",
infoflag_nodedisplacement, set_infobuttons_cmd);
AddVariable(&menu, "original", "node's original position",
infoflag_nodeoriginalpos, set_infobuttons_cmd);
AddVariable(&menu, "force", "applied force on node",
infoflag_nodeforce, set_infobuttons_cmd);
#ifdef THERMAL
AddVariable(&menu, "temperature", "temperature of a node",
infoflag_nodetemperature, set_infobuttons_cmd);
#endif // THERMAL
}
NodeInfo::~NodeInfo() {
hide();
delete_fl_group(nodeinfo);
/*
fl_delete_object(nodeinfo);
fl_free_object(info_mouseposition);
fl_free_object(nodeinfotext);
fl_free_object(info_nodetype);
fl_free_object(info_nodeindex);
fl_free_object(info_nodeposition);
fl_free_object(info_nodedisplacement);
fl_free_object(info_nodeoriginalpos);
fl_free_object(nodeinfo);
*/
menu.RemoveOption("nodetype");
menu.RemoveOption("nodeindex");
menu.RemoveOption("position");
menu.RemoveOption("displacement");
menu.RemoveOption("original");
menu.RemoveOption("force");
#ifdef THERMAL
menu.RemoveOption("temperature");
#endif // THERMAL
}
void NodeInfo::show() {
fl_show_object(nodeinfo);
setcursor(*infocursor);
}
void NodeInfo::hide() {
fl_hide_object(nodeinfo);
unsetcursor();
}
void NodeInfo::set_infobuttons() const {
fl_set_button(info_mouseposition, infoflag_mouseposition);
fl_set_button(info_nodetype, infoflag_nodetype);
fl_set_button(info_nodeindex, infoflag_nodeindex);
fl_set_button(info_nodeposition, infoflag_nodeposition);
fl_set_button(info_nodedisplacement, infoflag_nodedisplacement);
fl_set_button(info_nodeforce, infoflag_nodeforce);
#ifdef THERMAL
fl_set_button(info_nodetemperature, infoflag_nodetemperature);
#endif // THERMAL
}
void NodeInfo::set_info_nodetype() {
infoflag_nodetype = infoflag_nodetype_dflt =
fl_get_button(info_nodetype);
garcon()->log(menucommand() + "nodetype=" + to_charstring(infoflag_nodetype));
}
void FDCB_info_nodetype(FL_OBJECT *, long ptr) {
((NodeInfo*) ptr)->set_info_nodetype();
}
void NodeInfo::set_info_nodeindex() {
infoflag_nodeindex = infoflag_nodeindex_dflt =
fl_get_button(info_nodeindex);
garcon()->log(menucommand() + "nodeindex=" +
to_charstring(infoflag_nodeindex));
}
void FDCB_info_nodeindex(FL_OBJECT *, long ptr) {
((NodeInfo*) ptr)->set_info_nodeindex();
}
void NodeInfo::set_info_nodeposition() {
infoflag_nodeposition = infoflag_nodeposition_dflt =
fl_get_button(info_nodeposition);
garcon()->log(menucommand() + "position=" +
to_charstring(infoflag_nodeposition));
}
void FDCB_info_nodeposition(FL_OBJECT *, long ptr) {
((NodeInfo*) ptr)->set_info_nodeposition();
}
void NodeInfo::set_info_nodedisplacement() {
infoflag_nodedisplacement = infoflag_nodedisplacement_dflt =
fl_get_button(info_nodedisplacement);
garcon()->log(menucommand() + "displacement=" +
to_charstring(infoflag_nodedisplacement));
}
void FDCB_info_nodedisplacement(FL_OBJECT *, long ptr) {
((NodeInfo*) ptr)->set_info_nodedisplacement();
}
void NodeInfo::set_info_nodeoriginalpos() {
infoflag_nodeoriginalpos = infoflag_nodeoriginalpos_dflt =
fl_get_button(info_nodeoriginalpos);
garcon()->log(menucommand() + "original=" +
to_charstring(infoflag_nodeoriginalpos));
}
void FDCB_info_nodeoriginalpos(FL_OBJECT *, long ptr) {
((NodeInfo*) ptr)->set_info_nodeoriginalpos();
}
void NodeInfo::set_info_nodeforce() {
infoflag_nodeforce = infoflag_nodeforce_dflt =
fl_get_button(info_nodeforce);
garcon()->log(menucommand() + "force=" + to_charstring(infoflag_nodeforce));
}
void FDCB_info_nodeforce(FL_OBJECT*, long ptr) {
((NodeInfo*) ptr)->set_info_nodeforce();
}
#ifdef THERMAL
void NodeInfo::set_info_nodetemperature() {
infoflag_nodetemperature = infoflag_nodetemperature_dflt =
fl_get_button(info_nodetemperature);
garcon()->log(menucommand() + "temperature=" + to_charstring(infoflag_nodetemperature));
}
void FDCB_info_nodetemperature(FL_OBJECT*, long ptr) {
((NodeInfo*) ptr)->set_info_nodetemperature();
}
#endif // THERMAL
void NodeInfo::clickhandler(const MouseClick &click) {
if(!gridinit()) return;
grid->fix_masters(); // make sure flags are correct in nodes
garcon()->msout << "-----------" << endl;
if(infoflag_mouseposition)
garcon()->msout << " mouse at x=" << click.coord.x
<< " y=" << click.coord.y << endl;
Node *n = grid->findNode(click.coord);
if(!n) return;
if(infoflag_nodetype)
garcon()->msout << " type: " << n->tag() << n->parameters() << " " <<
n->flags() << endl;
if(infoflag_nodeindex)
garcon()->msout << " index: " << n->index << endl;
if(infoflag_nodeposition)
garcon()->msout << " x, y: "
<< n->position().x << ", " << n->position().y << endl;
if(infoflag_nodedisplacement)
garcon()->msout << " dx, dy: "
<< n->displacement().x << ", " << n->displacement().y << endl;
if(infoflag_nodeoriginalpos)
garcon()->msout << " x0, y0: "
<< n->original().x << ", " << n->original().y << endl;
if(infoflag_nodeforce) {
MeshCoord f = n->force();
garcon()->msout << " fx, fy: " << f.x << ", " << f.y << endl;
}
#ifdef THERMAL
if(infoflag_nodetemperature)
garcon()->msout << " T: " << n->voltage() << endl;
#endif // THERMAL
}
syntax highlighted by Code2HTML, v. 0.9.1