generate_spice_cable_bundle_model
18.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
#!/bin/bash
#
# This is a script to generate a spice cable model
# then run a validation test problem to
# check that it is working OK
#
# Copyright (C) 2015 Chris Smartt
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. See license.txt for more details.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
source gnuplot_functions
# get the path to the TEST_CASE directory- note a special method is used in cygwin...
if [ "$OSTYPE" == "cygwin" ]; then
TEST_CASE_DIRECTORY=$( cygpath -m $(pwd) )
else
TEST_CASE_DIRECTORY=$( pwd )
fi
PROJECT_DIRECTORY2=$( dirname ${TEST_CASE_DIRECTORY} )
PROJECT_DIRECTORY=$( dirname ${PROJECT_DIRECTORY2} )
LIBRARY_OF_MODELS_TOP_LEVEL="${TEST_CASE_DIRECTORY}/MOD"
LIBRARY_OF_CABLE_MODELS="${LIBRARY_OF_MODELS_TOP_LEVEL}/CABLE_MODELS"
LIBRARY_OF_BUNDLE_MODELS="${LIBRARY_OF_MODELS_TOP_LEVEL}/BUNDLE_MODELS"
LIBRARY_OF_SPICE_MODELS="${LIBRARY_OF_MODELS_TOP_LEVEL}/SPICE_MODELS"
# the following keeps the circuit symbols in the local directory
SYMBOL_DIR="./"
# the following puts circuit symbols in the gschem directory
#SYMBOL_DIR="/usr/share/gEDA/sym/local"
EXECUTABLE_DIR="${PROJECT_DIRECTORY}/bin"
NGSPICE_SUFFIX="_Ngspice.cir"
# NOTE: you may need to change ownership of SYMBOL_DIR with something like the following command:
# sudo chown chris:chris /usr/share/gEDA/sym/local
FULL_TEST_CASE_LIST="FD_TWINAX2_OVER_GROUND_FASTHENRY
FD_TWINAX2_OVER_GROUND_LAPLACE
"
ERROR_STRING="\
Run using the following command:
generate_spice_cable_bundle_model action
action is the process to perform:
action=run NAME : Generate cable models, bundle model and
Spice bundle model and validation spice model
as required for the test case NAME.
Run ngspice on the validation model and compare
the spice result against the analytic solution
action=plot NAME : Plot the results of the spice validation model and
analytic solution to x11 terminal
action=plot_wxt NAME : Plot the results of the spice validation model and
analytic solution to wxt terminal
action=plot_jpg NAME : Plot the results of the spice validation model and
analytic solution to .jpg file
action=plot_ref NAME : Plot the spice validation model results against
reference results to x11 terminal
action=plot_ref_wxt NAME : Plot the spice validation model results against
reference results to wxt terminal
action=plot_ref_jpg NAME : Plot the spice validation model results against
reference results to jpg file
action=plot_bundle NAME : Plot the bundle cross section to x11 terminal
action=plot_bundle_wxt NAME : Plot the bundle cross section to wxt terminal
action=plot_bundle_jpg NAME : Plot the bundle cross section to jpg file
action=plot_bundle_png NAME : Plot the bundle cross section to png file
action=plot_bundle_svg NAME : Plot the bundle cross section to svg file
action=reference NAME : Update the reference results and the difference
between the spice model and validation model
with the current set of results
action=check_error NAME : Quick check that the difference between the
spice model and validation model is the same as
for the reference data set
action=clean NAME : Remove all files except those required to set up
the problem and the reference results.
action=clean_all NAME : Remove all files including the reference results.
action=clean_mod NAME : Remove all files in the specified MOD directories.
NAME can be one of the existing test cases or left blank to run all the test cases
in the FULL_TEST_CASE_LIST defined in this script
"
if [ "$#" = "0" ] ; then
# there is no action specified so write the error string to the screen and exit
echo "$ERROR_STRING"
elif [ "$#" = "1" ] ; then
# no test case is specified so use the full test case list
TEST_CASE_LIST=$FULL_TEST_CASE_LIST
else
# the second argument gives the test case to be run
TEST_CASE_LIST=$2
fi
ACTION=$1
if [ "$ACTION" = "clean_mod" ]; then
pushd .
cd $LIBRARY_OF_CABLE_MODELS
rm -f *.cable
popd
pushd .
cd $LIBRARY_OF_BUNDLE_MODELS
rm -f *.bundle
popd
pushd .
cd $LIBRARY_OF_SPICE_MODELS
rm -f *.lib
popd
pushd .
cd $SYMBOL_DIR
rm -f *.asy *.sym
popd
exit
fi
# set up a new status file with the run command and action as a header
echo "generate_spice_cable_bundle_model $ACTION
" > status
ERROR=" "
# Loop over the specified test cases
for TEST_CASE in $TEST_CASE_LIST
do
# Check that the test case directory exists
if [ ! -d "$TEST_CASE" ]; then
echo "${TEST_CASE} *** FAILED ***: does not exist" >> status
continue
fi
echo "Running test case: ${TEST_CASE}"
if [ "$ACTION" = "run" ] ; then
ERROR=' '
# Run the test case(s) specified...
cd $TEST_CASE
if [ ! -d RUN_DIRECTORY ]; then
# if the RUN_DIRECTORY doesn't exist then make it
mkdir RUN_DIRECTORY
else
# if the RUN_DIRECTORY exists then empty the directory to run the test in
echo "arg 3: $3"
if [ "$3" != "spice_only" ]; then
rm -f RUN_DIRECTORY/*
echo " Cleaning RUN_DIRECTORY"
fi
fi
# create a sed command which will substitute the local MOD directory for the test cases
echo "{
s/LIBRARY_OF_CABLE_MODELS/${LIBRARY_OF_CABLE_MODELS//\//\\/}/g
s/LIBRARY_OF_BUNDLE_MODELS/${LIBRARY_OF_BUNDLE_MODELS//\//\\/}/g
s/LIBRARY_OF_SPICE_MODELS/${LIBRARY_OF_SPICE_MODELS//\//\\/}/g
s/SYMBOL_DIR/${SYMBOL_DIR//\//\\/}/g
}" > sed_command
# Check that the appropriate files required to specify the inputs to the processes
# are present for a viable run and copy the files into the RUN_DIRECTORY
CABLE_FILE_LIST=$(ls *.cable_spec )
for CABLE_FILE in $CABLE_FILE_LIST
do
# run sed to copy to a new file with the library paths set appropriately
sed -f sed_command $CABLE_FILE > RUN_DIRECTORY/$CABLE_FILE
done
NUMBER_OF_BUNDLE_SPEC_FILES=$(ls *.bundle_spec 2> /dev/null | wc -l)
echo "NUMBER_OF_BUNDLE_SPEC_FILES $NUMBER_OF_BUNDLE_SPEC_FILES"
if [ "$NUMBER_OF_BUNDLE_SPEC_FILES" -gt "1" ]; then
cd ..
echo "${TEST_CASE} *** FAILED ***: no more than one .bundle_spec file is expected" >> status
continue
elif [ "$NUMBER_OF_BUNDLE_SPEC_FILES" == "1" ]; then
FILENAME=$(ls *.bundle_spec)
sed -f sed_command $FILENAME > RUN_DIRECTORY/$FILENAME
fi
NUMBER_OF_SPICE_MODEL_SPEC_FILES=$(ls *.spice_model_spec 2> /dev/null | wc -l)
echo "NUMBER_OF_SPICE_MODEL_SPEC_FILES $NUMBER_OF_SPICE_MODEL_SPEC_FILES"
if [ "$NUMBER_OF_SPICE_MODEL_SPEC_FILES" -gt "1" ]; then
cd ..
echo "${TEST_CASE} *** FAILED ***: no more than one .spice_model_spec file is expected" >> status
continue
elif [ "$NUMBER_OF_SPICE_MODEL_SPEC_FILES" == "1" ]; then
FILENAME=$(ls *.spice_model_spec)
# copy the spice_model_spec file and set the correct SYMBOL_DIR
sed -f sed_command ${FILENAME} > RUN_DIRECTORY/${FILENAME}
fi
# Go into the run directory to run the test case
cd RUN_DIRECTORY
if [ "$3" != "spice_only" ]; then
# STAGE 1. GENERATE THE CABLE MODEL(S)
# STAGE 1.1: look for any files with the extension .cable_spec
echo " "
CABLE_FILE_LIST=$(ls *.cable_spec 2> /dev/null)
# STAGE 1.2:loop through these files runninng cable_model_builder for each of them
CABLE_MODEL_BUILDER_STATUS="OK"
for CABLE_FILE in $CABLE_FILE_LIST
do
CABLE_NAME=$(basename $CABLE_FILE .cable_spec)
${EXECUTABLE_DIR}/cable_model_builder ${CABLE_NAME}
# Check that the process finished correctly
read CHECK < run_status
if [ "$CHECK" != "cable_model_builder:Finished_Correctly" ]; then
# We need to organise the logic here such that the test case fails and
# the system goes on to the next test case, not the next CABLE_FILE...
echo "${TEST_CASE} *** FAILED ***: cable_model_builder $CABLE_FILE" >> ../../status
CABLE_MODEL_BUILDER_STATUS="failed"
continue
fi
done
# exit the test case if the cable model builder failed
if [ "$CABLE_MODEL_BUILDER_STATUS" = "failed" ]; then
cd ../..
continue
fi
# STAGE 2. GENERATE THE BUNDLE MODEL
echo " "
# STAGE 2.1: count files with the extension .bundle_spec and return with an error if the result is not 0 or 1
if [ "$NUMBER_OF_BUNDLE_SPEC_FILES" == "1" ]; then
FILENAME=$(ls *.bundle_spec)
CABLE_BUNDLE_NAME=$(basename $FILENAME .bundle_spec)
${EXECUTABLE_DIR}/cable_bundle_model_builder ${CABLE_BUNDLE_NAME}
# Check that the process finished correctly
read CHECK < run_status
if [ "$CHECK" != "cable_bundle_model_builder:Finished_Correctly" ]; then
cd ../..
echo "${TEST_CASE} *** FAILED ***: cable_bundle_model_builder" >> status
continue
fi
fi
#spice_only
fi
# STAGE 3.GENERATE THE SPICE CABLE MODEL
echo " "
# STAGE 3.1: Count files with the extension .spice_model_spec and return with an error if the result is not 1
if [ "$NUMBER_OF_SPICE_MODEL_SPEC_FILES" == "1" ]; then
# STAGE 3.2:run the spice cable bundle model builder
FILENAME=$(ls *.spice_model_spec)
SPICE_CABLE_BUNDLE_NAME=$(basename $FILENAME .spice_model_spec)
${EXECUTABLE_DIR}/spice_cable_bundle_model_builder ${SPICE_CABLE_BUNDLE_NAME}
# Check that the process finished correctly
read CHECK < run_status
if [ "$CHECK" != "spice_cable_bundle_model_builder:Finished_Correctly" ]; then
cd ../..
echo "${TEST_CASE} *** FAILED ***: spice_cable_bundle_model_builder" >> status
continue
fi
# STAGE 4.RUN NGSPICE
# STAGE 4.1: COUNT FILES WITH THE EXTENSION .CIR AND RETURN WITH AN ERROR IF THE RESULT IS NOT 1
if [ $(ls *${NGSPICE_SUFFIX} | wc -l) != "1" ]; then
cd ../..
echo "${TEST_CASE} ERROR: a single .cir file is expected"
continue
fi
SPICE_INPUT_FILE=$(ls *${NGSPICE_SUFFIX})
SPICE_PROBLEM_NAME=$( basename $SPICE_INPUT_FILE .cir )
SPICE_OUTPUT_NAME="spice_solution.dat"
echo " "
echo "ngspice:Started"
ngspice -b $SPICE_INPUT_FILE -o $SPICE_OUTPUT_NAME
# check that the process finished correctly
NGPSICE_STATUS=$?
if [[ $NGPSICE_STATUS != 0 ]]; then
cd ../..
echo "${TEST_CASE} *** FAILED ***: ngspice, error code:$NGPSICE_STATUS" >> status
continue
else
echo "${TEST_CASE} ngspice:Finished_correctly"
fi
# Stage 5: COMPARE THE RUN_DIRECTORY OF THE SPICE MODEL AGAINST THE ANALYTIC MODEL USING THE COMPARE_RUN_DIRECTORY PROCESS
# create an input file for the result comparison process
echo "analytic_solution.dat
1
2
$SPICE_OUTPUT_NAME
2
3
result_comparison.dat
" > compare_results_in.txt
echo " "
${EXECUTABLE_DIR}/compare_results < compare_results_in.txt
read CHECK < run_status
if [ "$CHECK" != "compare_results:Finished_Correctly" ]; then
cd ../..
echo "${TEST_CASE} *** FAILED ***: compare_results" >> status
continue
fi
# add the error between spice and analytic solutions to the status line
read ERROR < result_comparison.dat
# Create a file 'finished_correctly' to indicate that the run has finished_correctly
touch finished_correctly
# .spice_model_spec file exists
fi
cd ../..
# finished "$ACTION" = "run"
elif [ "$ACTION" = "plot_bundle" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=x11
write_gnuplot_plot_bundle
cd ../..
elif [ "$ACTION" = "plot_bundle_jpg" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=jpeg
OUTPUT_FILE=${TEST_CASE}_bundle_cross_section.jpg
write_gnuplot_plot_bundle
cd ../..
elif [ "$ACTION" = "plot_bundle_wxt" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=wxt
write_gnuplot_plot_bundle
cd ../..
elif [ "$ACTION" = "plot_bundle_png" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=png
OUTPUT_FILE=${TEST_CASE}_bundle_cross_section.png
write_gnuplot_plot_bundle
cd ../..
elif [ "$ACTION" = "plot_bundle_svg" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=svg
OUTPUT_FILE=${TEST_CASE}_bundle_cross_section.svg
write_gnuplot_plot_bundle
cd ../..
elif [ "$ACTION" = "clean" ]; then
cd $TEST_CASE
# Empty the directory to run the test in
rm -f RUN_DIRECTORY/*
rm -f sed_command
cd ..
elif [ "$ACTION" = "clean_all" ]; then
cd $TEST_CASE
# Empty the directory to run the test in
rm -f RUN_DIRECTORY/*
rm -f sed_command
cd ..
else
# All other actions assume that the test case has been run so check that this is the case
if [ ! -d ${TEST_CASE}/RUN_DIRECTORY ]; then
# if the RUN_DIRECTORY doesn't exist then the problem can't have been run
echo "${TEST_CASE} *** FAILED ***: The RUN_DIRECTORY is missing" >> status
continue
fi
if [ ! -f ${TEST_CASE}/RUN_DIRECTORY/finished_correctly ]; then
# if the RUN_DIRECTORY/finished_correctly file doesn't exist then
# the run cannot have proceeded as far as producing spice simulation results
echo "${TEST_CASE}: *** No simulation results are available for action: $ACTION " >> status
continue
fi
# no other checks SHOULD be necessary now...
# read the analytic solution file header to work out the type of simulation which has been run
read HEADER < ${TEST_CASE}/RUN_DIRECTORY/analytic_solution.dat
if [ "$HEADER" = "#LOG_FREQUENCY_DATA" ]; then
# Set the gnuplot parameters for a Log frequency plot
XLABEL=Frequency\(Hz\)
YLABEL=V\(f\)
XSCALE=logscale
elif [ "$HEADER" = "#LIN_FREQUENCY_DATA" ]; then
# Set the gnuplot parameters for a Linear frequency plot
XLABEL=Frequency\(Hz\)
YLABEL=V\(f\)
XSCALE=nologscale
elif [ "$HEADER" = "#TIME_DOMAIN_DATA" ]; then
# Set the gnuplot parameters for a Time domain plot
XLABEL=Time\(s\)
YLABEL=V\(t\)
XSCALE=nologscale
else
echo "$TEST_CASE Error reading analytic solution file header :$HEADER" >> status
continue
# HEADER type
fi
TITLE=$TEST_CASE
OUTPUT_FILE=""
if [ "$ACTION" = "plot" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=x11
write_gnuplot_result
cd ../..
elif [ "$ACTION" = "plot_wxt" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=wxt
write_gnuplot_result
cd ../..
elif [ "$ACTION" = "plot_jpg" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=jpeg
OUTPUT_FILE=${TEST_CASE}_result.jpg
write_gnuplot_result
cd ../..
elif [ "$ACTION" = "plot_ref" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=x11
write_gnuplot_reference_result
cd ../..
elif [ "$ACTION" = "plot_ref_jpg" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=jpeg
OUTPUT_FILE=${TEST_CASE}_reference_result.jpg
write_gnuplot_reference_result
cd ../..
elif [ "$ACTION" = "plot_ref_wxt" ]; then
cd ${TEST_CASE}/RUN_DIRECTORY
TERMINAL=wxt
write_gnuplot_reference_result
cd ../..
elif [ "$ACTION" = "reference" ]; then
cd $TEST_CASE
cp RUN_DIRECTORY/result_comparison.dat result_comparison.dat_reference
cp RUN_DIRECTORY/spice_solution.dat spice_solution.dat_reference
cp RUN_DIRECTORY/analytic_solution.dat analytic_solution.dat_reference
cd ..
elif [ "$ACTION" = "check_error" ]; then
cd $TEST_CASE
cat RUN_DIRECTORY/result_comparison.dat
# Check whether there is an existing reference comparison file and if so check the difference
if [ -f result_comparison.dat_reference ]; then
cmp result_comparison.dat_reference RUN_DIRECTORY/result_comparison.dat
RETURN_CODE=$?
if [[ $RETURN_CODE == 0 ]]
then
cd ..
echo "Checking the current results against reference results: OK
"
echo "${TEST_CASE} FINISHED_CORRECTLY: error = reference error" >> status
continue
else
OLD_VALUE=$(cat result_comparison.dat_reference)
NEW_VALUE=$(cat RUN_DIRECTORY/result_comparison.dat)
cd ..
echo "Checking the current results against reference results: FAILED
"
echo "${TEST_CASE} *** FAILED ***: error != reference error" >> status
echo "Old value: $OLD_VALUE" >> status
echo "New value: $NEW_VALUE" >> status
continue
fi
else
cd ..
echo "${TEST_CASE} *** FAILED ***: The result_comparison.dat_reference file is missing" >> status
continue
fi
cd ..
else
echo " ERROR: unknown action, $ACTION"
exit 1
# end of ACTION options for ACTION != (run clean or clean_all)
fi
# end of ACTION options
fi
echo " "
echo "Test_case $TEST_CASE Finished correctly"
echo " "
echo "$TEST_CASE: Finished correctly $ERROR" >> status
done
if [ "$ACTION" = "clean_all" ] ; then
# clean the library of cable models
rm -rf $LIBRARY_OF_CABLE_MODELS/*
echo "Directory for individual cable models" > $LIBRARY_OF_CABLE_MODELS/readme.md
rm -rf $LIBRARY_OF_BUNDLE_MODELS/*
echo "Directory for cable bundle models and directories with the associated Spice cable bundle models" > $LIBRARY_OF_BUNDLE_MODELS/readme.md
rm -f status
fi
if [[ "$ACTION" != "clean" && "$ACTION" != "clean_all" ]] ; then
echo "__________________________________"
echo " "
echo "Completed all specified test cases"
echo "__________________________________"
echo " "
echo "STATUS:"
echo " "
cat status
echo " "
fi