# # Copyright 2000, 2001 (c) Pointwise, Inc. # All rights reserved. # ############################################################################### ## ## BlockDiagnose.glf ## ## Script with Tk interface to diagnose all enabled blocks in the system and ## write a written report. ## ############################################################################### # package require PWI_Glyph 1.1 global BlockDiagnoseArray catch { set scriptDir [file dirname [info script]] set logoFile [file join $scriptDir pwiLogo.glf] source $logoFile } namespace eval ::BlockDiagnose { # # buildGui - build all the widgets # proc buildGui { } { global BlockDiagnoseArray # Title bar wm title . "Block Diagnostics" set BlockDiagnoseArray(top) [frame .top] set f [frame $BlockDiagnoseArray(top).titleFrame] pack $f -side top -fill x -pady 5 set l [label $f.label -text "Block Diagnostics" -justify center] set font [$l cget -font] set fontFamily [font actual $font -family] set fontSize [font actual $font -size] set bigLabelFont [font create -family $fontFamily -weight bold \ -size [expr {2 * $fontSize}]] $l configure -font $bigLabelFont set regLabelFont [font create -family $fontFamily -weight bold \ -size [expr {int(1.25 * $fontSize)}]] pack $l -side top set f [frame $BlockDiagnoseArray(top).hr1 -height 2 -relief sunken \ -borderwidth 1] pack $f -side top -fill x -expand TRUE set BlockDiagnoseArray(gridFrame) \ [frame $BlockDiagnoseArray(top).gridFrame] # Create the columns of functions, min range values, and max range values set togCol 0 set minCol 1 set maxCol 2 set row 0 set l [label "$BlockDiagnoseArray(gridFrame).funcLabel" -text "Function" \ -justify center -font $regLabelFont] grid $l -column $togCol -row $row -sticky ew set l [label "$BlockDiagnoseArray(gridFrame).minLabel" -text "Min Range" \ -justify center -font $regLabelFont] grid $l -column $minCol -row $row -sticky ew set l [label "$BlockDiagnoseArray(gridFrame).maxLabel" -text "Max Range" \ -justify center -font $regLabelFont] grid $l -column $maxCol -row $row -sticky ew incr row foreach func $BlockDiagnoseArray(functions) { if {$BlockDiagnoseArray(${func}_Enabled)} { set state "normal" } else { set state "disabled" set BlockDiagnoseArray(${func}_On) 0 set BlockDiagnoseArray(${func}_Min) {} set BlockDiagnoseArray(${func}_Max) {} } if {$BlockDiagnoseArray(${func}_On)} { set entryState "normal" } else { set entryState "disabled" } # Toggle button set name "$BlockDiagnoseArray(gridFrame).tb_$func" set text "$BlockDiagnoseArray(${func}_Label)" set tb [checkbutton $name -indicatoron TRUE -state $state \ -variable BlockDiagnoseArray(${func}_On) -text $text \ -command [list ::BlockDiagnose::toggleCB $func]] grid $tb -column $togCol -row $row -sticky w # Min range set name "$BlockDiagnoseArray(gridFrame).min_$func" set e [entry $name -state $state \ -textvariable BlockDiagnoseArray(${func}_Min) \ -validate all -vcmd [list ::BlockDiagnose::validateCB $func "Min" %P]] setEntryState $e $entryState grid $e -column $minCol -row $row -sticky ew # Max range set name "$BlockDiagnoseArray(gridFrame).max_$func" set e [entry $name -state $state \ -textvariable BlockDiagnoseArray(${func}_Max) \ -validate all -vcmd [list ::BlockDiagnose::validateCB $func "Max" %P]] setEntryState $e $entryState grid $e -column $maxCol -row $row -sticky ew incr row } grid columnconfigure $BlockDiagnoseArray(gridFrame) $minCol -weight 1 grid columnconfigure $BlockDiagnoseArray(gridFrame) $maxCol -weight 1 pack $BlockDiagnoseArray(gridFrame) -side top -fill x -expand FALSE -padx 5 \ -pady 5 # Another separator set f [frame $BlockDiagnoseArray(top).hr2 -height 2 -relief sunken \ -borderwidth 1] pack $f -side top -fill x -expand FALSE # Buttons for controlling the output destination set outputFrame [frame $BlockDiagnoseArray(top).outputFrame] set l [label $outputFrame.l -text "Output:" -justify center] pack $l -side left -fill y -expand FALSE set BlockDiagnoseArray(output) "stdout" set rb [radiobutton $outputFrame.rb1 -indicatoron TRUE -value "stdout" \ -text "Console" -variable BlockDiagnoseArray(output) \ -command ::BlockDiagnose::changeOutputCB] pack $rb -side left -fill y -expand FALSE set rb [radiobutton $outputFrame.rb2 -indicatoron TRUE -value "file" \ -text "File" -variable BlockDiagnoseArray(output) \ -command ::BlockDiagnose::changeOutputCB] pack $rb -side left -fill y -expand FALSE set BlockDiagnoseArray(filenameEntry) [entry "$outputFrame.e" \ -state "disabled" -width 30 -textvariable BlockDiagnoseArray(filename)] pack $BlockDiagnoseArray(filenameEntry) -side left -fill x -expand TRUE \ -padx 3 set BlockDiagnoseArray(browseButton) [button "$outputFrame.b" \ -state "disabled" -text "..." -command ::BlockDiagnose::outputBrowserCB] pack $BlockDiagnoseArray(browseButton) -side left -fill none -expand FALSE setEntryState $BlockDiagnoseArray(filenameEntry) "disabled" pack $outputFrame -side top -fill x -expand TRUE -padx 5 -pady 5 # Another separator set f [frame $BlockDiagnoseArray(top).hr3 -height 2 -relief sunken \ -borderwidth 1] pack $f -side top -fill x -expand FALSE # Create the bottom buttons set f [frame $BlockDiagnoseArray(top).cmdFrame] set BlockDiagnoseArray(runButton) [button $f.run -width 8 -text "Run" \ -command [list ::BlockDiagnose::runCB]] pack $BlockDiagnoseArray(runButton) -side right -padx 5 set b [button $f.cancel -width 8 -text "Cancel" \ -command [list ::BlockDiagnose::cancelCB]] pack $b -side right -padx 5 if {![catch {pwiLogoCreate $f.logo 1} b]} { $b configure -bd 0 -relief flat pack $b -side left -padx 5 } pack $f -side top -fill x -expand FALSE -pady 5 pack $BlockDiagnoseArray(top) -expand TRUE -fill both updateRunStatus # Center the window ::tk::PlaceWindow . widget set w [winfo reqwidth $BlockDiagnoseArray(top)] set h [winfo reqheight $BlockDiagnoseArray(top)] wm resizable . 1 0 wm minsize . $w $h } # # showError - show an error message in a pop-up window # proc showError { msg title } { tk_messageBox -message $msg -title $title -type ok -icon error } # # printHeader - print a pretty header # proc printHeader { fd title } { set l [string length $title] set div [string repeat {=} 79] puts $fd "\n${div}" puts $fd "[string repeat { } [expr {int(40 - 0.5 * $l)}]]${title}" puts $fd "${div}\n" } # # diagnoseJac - diagnose cruncher for Jacobians # proc diagnoseJac { fd func } { global BlockDiagnoseArray printHeader $fd $BlockDiagnoseArray(${func}_Label) set nameLen 19 set headFmt "%-${nameLen}s%10s%10s%10s%10s%10s%10s" set dataFmt "%-${nameLen}s%10g%10g%10g%10d%10d%10d" set longFmt "%-s\n[string repeat { } ${nameLen}]%10g%10g%10g%10d%10d%10d" set leadSp [expr {$nameLen - 17}] set elFmt "[string repeat { } [expr {$leadSp > 0 ? $leadSp : 0}]]%-8s %8d" set cntFmt "$elFmt\n$elFmt\n$elFmt\n$elFmt\n$elFmt" set hash [string repeat {-} 9] set minValue $BlockDiagnoseArray(${func}_Min) set maxValue $BlockDiagnoseArray(${func}_Max) set rangeArgs [list] if {![string equal "" $minValue]} { lappend rangeArgs -min $minValue } else { set minValue "n/a" } puts $fd "Minimum Range Value: $minValue" if {![string equal "" $maxValue]} { lappend rangeArgs -max $maxValue } else { set maxValue "n/a" } puts $fd "Maximum Range Value: $maxValue\n" puts $fd [format $headFmt "Block Name" "Min" "Avg" "Max" \ "Below" "In Range" "Above"] set hashDiv [format $headFmt [string repeat {-} ${nameLen}] $hash $hash \ $hash $hash $hash $hash] puts $fd $hashDiv set count 0 foreach block $::BlockDiagnose::blocks { gg::blkReport $block jacData JACOBIAN set cmd [list gg::blkExamine $block data $func] foreach arg $rangeArgs { lappend cmd $arg } eval $cmd set bName [gg::blkName $block] if {[string length $bName] > 19} { set fmt $longFmt } else { set fmt $dataFmt } puts $fd [format $fmt $bName \ $data(valueMin) $data(valueAvg) $data(valueMax) \ $data(belowRange) $data(inRange) $data(aboveRange)] puts $fd [format $cntFmt \ "positive" $jacData(jacobianPos) \ "pos skew" $jacData(jacobianPosSkew) \ "zero" $jacData(jacobianZero) \ "neg skew" $jacData(jacobianNegSkew) \ "negative" $jacData(jacobianNeg)] # Add up the totals set numCells [expr {$data(belowRange) + $data(inRange) + $data(aboveRange)}] if {0 == $count} { set total(min) $data(valueMin) set total(max) $data(valueMax) set total(num) $numCells set total(avg) [expr {$data(valueAvg) * $numCells}] set total(low) $data(belowRange) set total(mid) $data(inRange) set total(upp) $data(aboveRange) set total(pos) $jacData(jacobianPos) set total(psk) $jacData(jacobianPosSkew) set total(zer) $jacData(jacobianZero) set total(neg) $jacData(jacobianNeg) set total(nsk) $jacData(jacobianNegSkew) } else { if {$data(valueMin) < $total(min)} { set total(min) $data(valueMin) } if {$data(valueMax) > $total(max)} { set total(max) $data(valueMax) } set total(num) [expr {$total(num) + $numCells}] set total(avg) [expr {$total(avg) + ($data(valueAvg) * $numCells)}] set total(low) [expr {$total(low) + $data(belowRange)}] set total(mid) [expr {$total(mid) + $data(inRange)}] set total(upp) [expr {$total(upp) + $data(aboveRange)}] set total(pos) [expr {$total(pos) + $jacData(jacobianPos)}] set total(psk) [expr {$total(psk) + $jacData(jacobianPosSkew)}] set total(zer) [expr {$total(zer) + $jacData(jacobianZero)}] set total(neg) [expr {$total(neg) + $jacData(jacobianNeg)}] set total(nsk) [expr {$total(nsk) + $jacData(jacobianNegSkew)}] } incr count update idletasks } set total(avg) [expr {$total(avg) / $total(num)}] puts $fd $hashDiv puts $fd [format $dataFmt "Total" \ $total(min) $total(avg) $total(max) \ $total(low) $total(mid) $total(upp)] puts $fd [format $cntFmt \ "positive" $total(pos) \ "pos skew" $total(psk) \ "zero" $total(zer) \ "neg skew" $total(nsk) \ "negative" $total(neg)] puts $fd "\n" puts $fd "\n" } # # diagnoseRange - crunch out a particular function for each block # proc diagnoseRange { fd func } { global BlockDiagnoseArray printHeader $fd $BlockDiagnoseArray(${func}_Label) set nameLen 19 set headFmt "%-${nameLen}s%10s%10s%10s%10s%10s%10s" set dataFmt "%-${nameLen}s%10g%10g%10g%10d%10d%10d" set longFmt "%-s\n[string repeat { } ${nameLen}]%10g%10g%10g%10d%10d%10d" set hash [string repeat {-} 9] set minValue $BlockDiagnoseArray(${func}_Min) set maxValue $BlockDiagnoseArray(${func}_Max) # puts $fd [string repeat "123456789|" 8] set rangeArgs [list] if {![string equal "" $minValue]} { lappend rangeArgs -min $minValue } else { set minValue "n/a" } puts $fd "Minimum Range Value: $minValue" if {![string equal "" $maxValue]} { lappend rangeArgs -max $maxValue } else { set maxValue "n/a" } puts $fd "Maximum Range Value: $maxValue\n" puts $fd [format $headFmt "Block Name" "Min" "Avg" "Max" \ "Below" "In Range" "Above"] set hashDiv [format $headFmt [string repeat {-} 19] $hash $hash $hash \ $hash $hash $hash] puts $fd $hashDiv set count 0 foreach block $::BlockDiagnose::blocks { set cmd [list gg::blkExamine $block data $func] foreach arg $rangeArgs { lappend cmd $arg } eval $cmd set bName [gg::blkName $block] if {[string length $bName] > ${nameLen}} { set fmt $longFmt } else { set fmt $dataFmt } puts $fd [format $fmt $bName \ $data(valueMin) $data(valueAvg) $data(valueMax) \ $data(belowRange) $data(inRange) $data(aboveRange)] # Add up the totals set numCells [expr {$data(belowRange) + $data(inRange) + $data(aboveRange)}] if {0 == $count} { set total(min) $data(valueMin) set total(max) $data(valueMax) set total(num) $numCells set total(avg) [expr {$data(valueAvg) * $numCells}] set total(low) $data(belowRange) set total(mid) $data(inRange) set total(upp) $data(aboveRange) } else { if {$data(valueMin) < $total(min)} { set total(min) $data(valueMin) } if {$data(valueMax) > $total(max)} { set total(max) $data(valueMax) } set total(num) [expr {$total(num) + $numCells}] set total(avg) [expr {$total(avg) + ($data(valueAvg) * $numCells)}] set total(low) [expr {$total(low) + $data(belowRange)}] set total(mid) [expr {$total(mid) + $data(inRange)}] set total(upp) [expr {$total(upp) + $data(aboveRange)}] } incr count update idletasks } set total(avg) [expr {$total(avg) / $total(num)}] puts $fd $hashDiv puts $fd [format $dataFmt "Total" \ $total(min) $total(avg) $total(max) \ $total(low) $total(mid) $total(upp)] puts $fd "\n" } # # run - do the crunching # proc run { } { global BlockDiagnoseArray if {[string equal $BlockDiagnoseArray(output) "file"]} { if {[catch {open $BlockDiagnoseArray(filename) "w"} fd]} { showError $fd "Opening File" return } } else { set fd "stdout" } set title "Block Diagnostics" set l [string length $title] set div1 [string repeat {*} 79] set div2 "**[string repeat { } 75]**" puts $fd "\n\n${div1}\n${div1}\n${div2}" set leadSp [expr {int(38 - 0.5 * $l)}] set trailSp [expr {75 - $l - $leadSp}] puts $fd "**[string repeat { } $leadSp]${title}[string repeat { } $trailSp]**" puts $fd "${div2}\n${div1}\n${div1}\n\n" foreach func $BlockDiagnoseArray(functions) { if {$BlockDiagnoseArray(${func}_On)} { $BlockDiagnoseArray(${func}_Evaluator) $fd $func } } if {[string equal $BlockDiagnoseArray(output) "file"]} { catch {file close $fd} } } # # runCB - callback for the run button # proc runCB { } { . configure -cursor watch update run exit } # # outputBrowserCB - callback for launching the file browser # proc outputBrowserCB { } { global BlockDiagnoseArray set types { {{Text Files} {.txt} } {{Log Files} {.log} } {{All Files} * } } set cmd [list tk_getSaveFile -title {Select Diagnostics Output File} \ -filetypes $types] set filename $BlockDiagnoseArray(filename) if {![string equal "" $filename]} { catch { set dir [file dirname $filename] if {![string equal "" $dir]} { lappend cmd -initialdir $dir } } catch { set name [file tail $filename] if {![string equal "" $name]} { lappend cmd -initialfile $name } } catch { set ext [file extension $filename] if {![string equal "" $ext]} { lappend cmd -defaultextension $ext } } } else { lappend cmd -defaultextension ".txt" } set filename [eval $cmd] if {![string equal "" $filename]} { set BlockDiagnoseArray(filename) $filename } } # # changeOutputCB - callback for changing the output type # proc changeOutputCB { } { global BlockDiagnoseArray if {[string equal "file" $BlockDiagnoseArray(output)]} { set state "normal" } else { set state "disabled" } setEntryState $BlockDiagnoseArray(filenameEntry) $state $BlockDiagnoseArray(browseButton) configure -state $state } # # cancelCB - callback for the cancel button # proc cancelCB { } { # Should only be called from GUI ::exit } # # setEntryState - controls the appearance of entry widgets # proc setEntryState { entry state } { set grey "#e0e0e0" set font "#000000" set error "#ffc0c0" set normal "#ffffff" switch -exact -- $state { "disabled" { $entry configure -background $grey -foreground $grey -state $state } "normal" { $entry configure -background $normal -foreground $font -state $state } default { $entry configure -background $error -foreground $font -state "normal" } } } # # toggleCB - callback for toggle buttons # proc toggleCB { func } { global BlockDiagnoseArray if {$BlockDiagnoseArray(${func}_On)} { set state "normal" checkRange $func "Min" $BlockDiagnoseArray(${func}_Min) } else { set state "disabled" setEntryState "$BlockDiagnoseArray(gridFrame).min_$func" "disabled" setEntryState "$BlockDiagnoseArray(gridFrame).max_$func" "disabled" set BlockDiagnoseArray(${func}_RangeValid) 1 } set minButton "$BlockDiagnoseArray(gridFrame).min_$func" set maxButton "$BlockDiagnoseArray(gridFrame).max_$func" $minButton configure -state $state $maxButton configure -state $state updateRunStatus } # # checkRange - check the min and max range values for validity # proc checkRange { func end newValue } { global BlockDiagnoseArray if {0 == $BlockDiagnoseArray(${func}_MinValid) || \ 0 == $BlockDiagnoseArray(${func}_MaxValid)} { set value 0 } else { if {[string equal $end "Max"]} { set minValue $BlockDiagnoseArray(${func}_Min) set maxValue $newValue } else { set minValue $newValue set maxValue $BlockDiagnoseArray(${func}_Max) } if {[string equal "" $minValue] || [string equal "" $maxValue]} { set value 1 } elseif {$minValue <= $maxValue} { set value 1 } else { set value 0 } } set BlockDiagnoseArray(${func}_RangeValid) $value set minButton "$BlockDiagnoseArray(gridFrame).min_$func" set maxButton "$BlockDiagnoseArray(gridFrame).max_$func" if {0 == $value} { setEntryState $minButton "error" setEntryState $maxButton "error" } else { setEntryState $minButton "normal" setEntryState $maxButton "normal" } return $value } # # validateCB - callback for changes to range text entry widgets # proc validateCB { func end newValue } { global BlockDiagnoseArray if {[string is double $newValue]} { set valid 1 } else { set valid 0 } set BlockDiagnoseArray(${func}_${end}Valid) $valid set rangeValid [checkRange $func $end $newValue] updateRunStatus return TRUE } # # updateRunStatus - sets the state of the run button # proc updateRunStatus { } { global BlockDiagnoseArray set activeFuncs 0 set state "normal" foreach func $BlockDiagnoseArray(functions) { if {$BlockDiagnoseArray(${func}_On)} { if {0 == $BlockDiagnoseArray(${func}_RangeValid)} { set state "disabled" break } incr activeFuncs } } if {0 == $activeFuncs} { set state "disabled" } $BlockDiagnoseArray(runButton) configure -state $state } # # setArray - conditionally sets an array element # proc setArray { arrayName overwrite element value } { upvar $arrayName a if {$overwrite || ![info exists a($element)]} { set a($element) $value } } # # init - initializes the BlockDiagnoseArray structure # proc init { } { global BlockDiagnoseArray set funcList [list] set labelList [list] set typeList [list] set evalList [list] foreach entry { {I_SIZE "I Size" "STRUCT" "diagnoseRange" } {J_SIZE "J Size" "STRUCT" "diagnoseRange" } {K_SIZE "K Size" "STRUCT" "diagnoseRange" } {VOLUME "Volume" "ANY" "diagnoseRange" } {I_RATIO "I Ratio" "STRUCT" "diagnoseRange" } {J_RATIO "J Ratio" "STRUCT" "diagnoseRange" } {K_RATIO "K Ratio" "STRUCT" "diagnoseRange" } {ASPECT_RATIO "Aspect Ratio" "ANY" "diagnoseRange" } {I_SMOOTHNESS "I Smoothness" "STRUCT" "diagnoseRange" } {J_SMOOTHNESS "J Smoothness" "STRUCT" "diagnoseRange" } {K_SMOOTHNESS "K Smoothness" "STRUCT" "diagnoseRange" } {MIN_ALPHA_SKEWNESS "Min Alpha Skewness" "ANY" "diagnoseRange" } {MAX_ALPHA_SKEWNESS "Max Alpha Skewness" "ANY" "diagnoseRange" } {JACOBIAN "Jacobians" "STRUCT" "diagnoseJac" } {EQUI_ANGLE_SKEWNESS "Equi-angle Skewness" "ANY" "diagnoseRange" } {EQUI_VOLUME_SKEWNESS "Equi-volume Skewness" "UNSTRUCT" "diagnoseRange" } } { foreach {function label type evaluator} $entry {break} lappend funcList $function lappend labelList $label lappend typeList $type lappend evalList $evaluator } setArray BlockDiagnoseArray TRUE "functions" $funcList foreach function $BlockDiagnoseArray(functions) \ label $labelList type $typeList evaluator $evalList { setArray BlockDiagnoseArray TRUE "${function}_Label" $label setArray BlockDiagnoseArray TRUE "${function}_Evaluator" $evaluator setArray BlockDiagnoseArray TRUE "${function}_Type" $type setArray BlockDiagnoseArray TRUE "${function}_MinValid" 1 setArray BlockDiagnoseArray TRUE "${function}_MaxValid" 1 setArray BlockDiagnoseArray TRUE "${function}_RangeValid" 1 setArray BlockDiagnoseArray FALSE "${function}_On" 0 setArray BlockDiagnoseArray FALSE "${function}_Enabled" 1 setArray BlockDiagnoseArray FALSE "${function}_Min" {} setArray BlockDiagnoseArray FALSE "${function}_Max" {} setArray BlockDiagnoseArray FALSE "filename" "" } } # # prepare - disabled invalid functions based on present block types # proc prepare { } { global BlockDiagnoseArray set haveStructured 0 set haveUnstructured 0 foreach block $::BlockDiagnose::blocks { gg::blkReport $block data STRUCTURE if {[string equal $data(type) "UNSTRUCTURED"]} { set haveUnstructured 1 } elseif {[string equal $data(type) "STRUCTURED"]} { set haveStructured 1 } if {$haveUnstructured && $haveStructured} { break } } if {$haveUnstructured} { foreach func $BlockDiagnoseArray(functions) { if {[string equal $BlockDiagnoseArray(${func}_Type) "STRUCT"]} { set BlockDiagnoseArray(${func}_Enabled) 0 } } } if {$haveStructured} { foreach func $BlockDiagnoseArray(functions) { if {[string equal $BlockDiagnoseArray(${func}_Type) "UNSTRUCT"]} { set BlockDiagnoseArray(${func}_Enabled) 0 } } } } # Get the list of enabled blocks set blocks [list] foreach block [gg::blkGetAll] { if {[gg::blkEnable $block]} { lappend blocks $block } } set numBlocks [llength $blocks] }; # End of namespace ::BlockDiagnose gg::tkLoad if {0 == $::BlockDiagnose::numBlocks} { wm withdraw . update idletasks ::BlockDiagnose::showError "No enabled blocks are present." \ "Block Diagnose" exit } else { ::BlockDiagnose::init ::BlockDiagnose::prepare ::BlockDiagnose::buildGui gg::tkLoop } gg::tkLoop # # DISCLAIMER: # TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, POINTWISE DISCLAIMS # ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED # TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE, WITH REGARD TO THIS SCRIPT. TO THE MAXIMUM EXTENT PERMITTED BY # APPLICABLE LAW, IN NO EVENT SHALL POINTWISE BE LIABLE TO ANY PARTY FOR # ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER # (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS # INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR # INABILITY TO USE THIS SCRIPT EVEN IF POINTWISE HAS BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE FAULT OR NEGLIGENCE OF # POINTWISE. #