Day8

重力式擁壁の安定計算

Topへ

Day7へ

Day9へ

はじめに

おいさんが学生時代からどうしてもしたかった重力式擁壁の安定計算を今回は挑戦しようと思います。
「なぜ、今更この計算をするの?」や「あたためすぎでしょ」といったご意見もあると思いますが、 実際には計算方法がぼんやりわかってもできませんでした。
なぜかというと、重力式擁壁の計算は、「試行くさび法」という繰り返し計算を必要とし、プログラムのスキルと ある程度の数学の知識がないと実現不可能な内容だったからです。
ただ、現在おいさんの趣味はこれしかないので、時間をかけてじっくりやっていこうと思い今回挑戦することにしました。

Step1

断面の決定

image

最初に、断面の決定をしたいと思います。
また、決定した断面の値からフォーム上に重力式擁壁の模式図を描画したいと思います。
そこで、フォーム上に「PictureBox」と「Button」を配置します。
これを使用し、まず線が描けるかやってみたいと思います。

image

「PictureBox」は画像を表示させるためのツールになります。なので、通常、プロパティの「Image」に表示させたい画像を 指定するのですが、今回はそうはいきません。
そこで、プログラムで画像を作成し、それを「PictureBox」に表示させたいと思います。

image

画像を表示する「PictureBox」の背景色を黒にしたいので、フォームをダブルクリックしそこに 「PictureBox」のBackColorを黒にするコードを入力します。

image

試し書きをします。
最初に、ビットマップ画像を作成します。作成するコードは、「 Bitmap _bitmap = new Bitmap(400, 400);」 になります。ここで_bitmapは変数になり、その変数に400pxサイズの画像を格納しています。(インスタンスというやつです。)
次に、このビットマップに描画ができるコードを書きます。(画像参照)
描画できる準備ができたので一旦画像を黒で塗りつぶします。これは、ボタンが押される都度、白紙の状態にしたいためです。
今回は、とりあえず線を描いてみます。コードは、「g.DrawLine(Pens.White, 10, 10, 100, 200);」になります。内容としては 白色で、始点座標(x1,y1)、この場合(10,10)から終点座標(x2,y2)、この場合(100,200)まで線を描くコードになります。 最後に、このビットマップを「PictureBox」の「Image」プロパティに転送します。

とりあえずこれで実行してみます。
無事白い線が描けています。
この画像からわかるとおり、原点は左上になり、右方向がx、下方向がyになることがわかると思います。

image
image

描画の練習が終わりましたので、実際に断面決定の内容に入りたいと思います。
まず、フォーム画面のレイアイウトです。
テキストボックスを4つ用意し、各断面寸法を入力できるようにします。
また、各断面の寸法定義のため、マンガ絵を用意しました。
ボタン名もここで「入力完了」に変更しています。

image

恒例の、文字が入力できないように入力制限を行います。
お馴染みのコードになります。

image

全角を半角に変換できる命令文が書けるようにその準備をします。
ソリューションエクスプローラーの「参照」を右クリックします。
そうするとメニューが表示されるので「参照の追加」をクリックします。

image

「参照マネージャー」ダイアログが表示されますので、「アセンブリ」を選択し、 表示されるアセンブリの一覧から 「Microsoft.VisualBasic」を選択し「OK」ボタンをクリックします。

image

コードを書く画面に移動し一番上の方に「using Microsoft.VisualBasic;」を追加します。
最近わかったのですが、ここに「using」で書いておくと、それ以降「using」以降の文字を省略できるようです。
なので、ここで指定をしていなければ、毎回関連するコードを書く場合、「Microsoft.VisualBasic.・・・・・」といった ように書かなければならないようです。たぶん・・・

image

それでは「button1_Click」イベント内のコードに戻ります。
まずは、4つのテキストボックスに入力漏れがあった場合の処理をします。

image

続いて4つのテキストボックスの入力データを取得します。
全角から半角に変換するため、ここでは文字列として取得します。
そして、全角文字がある場合、半角文字に変換します。
コードは画像のとおりです。
その文字列を数字に変換します。
コードは画像のとおりです。

image

それでは「PictureBox」に入力された値で模式図を表示したいと思います。
まずは、画像のとおり①~④までの座標を決めます。
底盤の左側を①とし、その座標を(0,0)とすると残りの箇所の座標は画像のとおりとなります。
これをコード入力していきます。

image

それでは、「button1_Click」イベントのコードに戻ります。
それぞれの座標を変数「coordinateX」もしくは「coordinateY」として、値を格納します。
コードは画像のとおりです。

image

座標が決まりましたので、次は表示倍率を決めたいと思います。
現在設定しているビットマップ画像サイズは400px✕400pxです。ですのでこのサイズにほどよく表示できるようにしたいと思います。
まず、座標の中の数値で最大値を知る必要があります。最大値になれる座標の候補はx方向だとx4であり、y方向ではy2もしくはy3になります。
そこで、x4とy2(y3)の値の大きな方が最大値になります。一方、画像は余白として50pxを確保したいので300px✕300pxの範囲に模式図を表示 することにします。
ですので、コードとしては300pxを座標の最大値で除した値を表示倍率とします。

image

実際のコードは画像のとおりです。
この中で、表示用の座標計算をしていますが、格納する変数をfloat型という ものにしています。
これは、このあと使用するGraphicsオブジェクトのDrawLine関数に入れる値(引数)の型が float型でないといけない条件になっているためです。
ただし、座標の型はdouble型なので型変換をする必要があります。そこで便利なのがキャスト とよばれる方法です。単純に変換したい型名を( )で囲んでそれを変更したい変数の前に付け加えるだけで 型変換可能になるようです。

image

先程書いた描画コードを改造します。
改造したコードは画像のとおりとなります。
本当は、もう少しこだわって中央表示するようにすれば良いのでしょうが おいさんは根性がないのでしません。

image

ここで、実行してみます。
無事、模式図が表示されました(感動)。奇跡的にもここまでで大きなエラーも無く辿り着きました。
ここまではもっているようです。このまま続きますように。

image image

最後に訂正をさせてください。
今回の座標(躯体)は、他の箇所でも使用する必要があります。
なので「button_Click1」イベントの1階層上で変数を宣言する必要がありました。
よって、コードを画像のとおり追加と修正をします。

Step2

擁壁背面形状の決定

image

安定計算の条件として、擁壁の背面形状を決定する必要があります。
背面形状も画像に示すような座標で決定したいと思います。
また、併せて上載荷重も入力できるようにします。

image

背面形状を入力するフォーム画面です。
背面形状は4つまで入力できるようにしました。
画像のt5~t16のt表記はtextBoxの略です。

image

それではコードを入力していきます。
最初は、得意の追加したテキストボックスに文字が入力できなよう入力制限をします。
ただ、今回、テキストボックスが多いので大変です。

image

次に、フォーム画面の背面形状決定の「入力完了」ボタンをダブルクリックします。
コードが書ける画面(button2.Click)に移動しますので、まず、テキストボックスに何も入力されていない 場合の処理を書きます。
今回の場合、最低限「tetxBox5」と「textBox6」が入力されていれば良いので、その場合の処理にしています。

image

次の処理に行く前に、「button_Click2」イベント以外でも取得した値が使用できるように 変数を宣言します。
宣言場所は、躯体座標の変数宣言の下にしています。

image

変数を宣言しましたので、入力値を取得したいところですが、もう一つやることがあります。
背面形状の値は、条件次第ではすべてのテキストボックスに入力することがありません。
そこで、どこまで入力されているか把握する必要があります。(把握パターンを格納するため先程変数「inDatanum」を宣言しました)
おいさんは、あまり知恵がないので、「button_Click2」イベントに戻りif文で場合分けをしました。
Y座標の入力の可否によって入力パターンを4つに分けてみました。ここで「!=」とありますが、 これは「イコールではない」という意味になります。

image

switch文を用いて、場合分けし入力データを取得します。また、同時に全角→半角変換と文字→数値変換もしています。
画像は、すべての値が入力されている場合のコードになります。

image

switch文の続きです。
画像は、3点までの値が入力されている場合のコードになります。

image

switch文の続きです。
画像は、2点までの値が入力されている場合のコードになります。

image

switch文の続きです。
画像は、いずれのケースにも該当しない、つまり1点のみの値が入力されている場合のコードになります。

image

背面形状の座標が固まりましたので、「PictureBox」に描画をします。
まずは、最大値より表示倍率を決定する必要がありますが、前提条件として躯体断面が決定している必要があります。
もし、断面決定せずに背面形状の決定の「入力完了」ボタンを押してしまうと、エラーになってしまう恐れがあります。
なので、まずは、躯体断面が決定しているかのフラグをたてます。
フラグ用の変数は、コードの上位の層にしたいので、「背面形状関係の変数宣言」の下に宣言します。
また、変数の型は「bool」型にします。(trueもしくはfalseの2択しか必要しないため)

image

「button_Click1」イベントの最後に「btn1.end」フラグを「true」にするコードを追加します。
これにより、躯体断面の決定は完了していることになります。

image

「button_Click2」イベントのコードに戻ります。
「btn1.end」フラグの設定ができたので、if文で「true」の場合のみその後の処理を行うようにします。
ここでは、描画倍率を決定します。倍率を決定するには、座標の最大値を知る必要がありますが、背面形状の末端を最大値とし て、その値で画像サイズ(350px)を割ることにしました。
また、形状によって条件が異なるので、やはり「switch文」を用いて場合分けし、最大値を求めることにしました。
なんだか、ダラダラとしたコードになってきましたが、素人のおいさんなのでご了承ください。

image

続いて表示用の座標計算をしています。
背面形状の座標は擁壁③を始点にしていたので、擁壁③の座標を足しています。
また、背面形状の座標計算においては、またまた形状によって条件が異なるため、場合分けをする必要があります。
これまで、switch文を使用してきましたが、気分を変えてif文にしてみました。

image

描画コードになります。
ここでも、形状によって条件が異なるため、場合分けをしながら描画することにしました。
最後に背面形状が決定したので、「btn2end」フラグを「true」にしてます。

image

訂正です。(何回もすみません)
「button_Click2」イベントのコードを少し戻り、入力データの読み込みコードを画像のとおり変更しました。
理由としては、上載荷重のテキストボックスに何も入力されていない場合エラーになるためです。
なので、その対応としてif文を使用し未入力箇所は0を入れ込むコードにしました。(他の「case」も同様に変更しています。)

image

ここで、実行してみます。
かなり長いコードを書いた割には、ただ描画するだけの機能のみです。
とにもかくにも、背面形状の決定はこれで完了になります。

Step3

土質諸元の決定

image

土質諸元の入力を行えるようにします。
といっても、一番最初に入力するのはコンクリートの単位重量といういきなり違う内容です。修正するのが面倒なのでご容赦を。
フォーム画面のレイアウトは画像のとおりにしました。
実際の入力は、「textBox22」までで、以降は内部摩擦角で決まる値なのでバックカラーの色を変えています。

image

恒例の入力制限をします。
「textBox22」まで行うようにしました。

image

壁面摩擦角は背面土の内部摩擦角より決まる角度になります。そこで、このテキストボックス(textBox19)に入力された 時点で、壁面摩擦角を決定するようにします。
内部摩擦角と壁面摩擦角との関係は画像のとおりとします。

image

テキストボックスのイベントに「TextChange」がありましたので、これを使います。
「textBox19」を選択し、イベント(カミナリマーク)から、「TextChange」をダブルクリックします。

image

先程の壁面摩擦角の計算式をコードにしました。
一応、空白入力のときは、何もしないことにしました。

image

実行してみます。
内部摩擦角を入力したら、無事、壁面摩擦角が表示されました。

image

次に、土質諸元の入力値を格納する変数を宣言します。
この変数も、各所で使用したいので、上層で宣言するようにします。

image

ついでにその下の入力完了フラグも追加します。
追加するフラグは、土質諸元の「入力完了」ボタン「button3」になります。

image

フォーム上の「button3」をダブルクリックしコード入力画面を開きます。
まず、テキストボックスの入力値を取得します。
これまでどおり、未入力の処理から、入力データの取得、全角→半角変換および文字→数字変換を行います。

Step4

許容応力度の決定

image

まず、フォームのデザインです。今回は、コンボボックスも使用しています。
テキストボックスは5つ用意しています。このテキストボックスは直接入力せず、コンボボックスの選択により 自動で表示するように使います。なので、バックカラーを変更しています。

image

許容応力度については画像のとおりとします。

image

許容応力度の入力値を格納する変数を宣言します。
この変数も、各所で使用したいので、上層で宣言するようにします。
また、その下の入力完了フラグも追加します。
追加するフラグは、許容応力度の決定の「入力完了」ボタン「button4」になります。

image

テキストボックスに直接入力されてもいいように恒例の入力制限をします。

image

次はコンボボックスの初期設定をします。
comboBox1を選択し、そのプロパティから「Items」を選択します。

image

画像に示す画面が表示されます。
そこに、コンクリート設計基準強度「18~24」まで入力し、OKボタンを押します。

image

コンボボックスにキー入力ができないようにします。(選択のみ可能)
コンボボックスの「DropDownStyle」プロパティを「ComboBoxStyle.DropDownList」にします。

image

コンボボックスのイベントに「TextChange」がありましたので、これを使います。
「comboBox1」を選択し、イベント(カミナリマーク)から、「TextChange」をダブルクリックします。

image

コードが書ける画面になったら、まず、コンボボックスが未選択もしくは空白の場合、 メッセージをだし、処理を終えるようにします。
上記の条件をクリアした場合は、switch文で場合分けし、各変数に格納することにしました。

image

決定した許容応力度をフォーム画面に表示します。
「comboBox1」は選択で表示されているので、テキストボックスのみ表示するコードを書きます。

image

最後に入力完了の「button4」をダブルクリックしコードを書ける画面へと移ります。 変数はすでに格納済みなので、ここではフラッグを「true」にするだけの処理になります。
ただし、フラッグ変更前に、すべての項目が入力されているか確認するようにします。

Step5

いよいよ計算(躯体自重と重心の算定)

座標法について

image

重力式擁壁の躯体自重を知るには躯体断面積を求める必要があります。面積を求める式はいろいろありますが、ここでは 座標法により面積を求めることにします。
まず、座標法を理解するために画像の図形を例に面積を算出してみます。

image

例の図形は単純な10✕7の長方形になります。
これを座標法により表に表すと画像のとおりとなります。
左の2列は長方形4点の座標XとYになります。
左から3列目は1つ前のX座標になります。つまり、①の1つ前は④になりますので、そのX座標になります。
左から4列目は反対に1つ先のX座標になります。その他の列は表示のとおりです。
最終的に、答えは70となりしっかり面積が算出できています。

image

座標法の計算をメインコードに書くとさらにごちゃごちゃするので、別クラスを用意してそこで計算するようにします。
それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「重力式擁壁」のところで右クリックします。
すると、画像のとおり、選択できる画面が出てきますので、「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。
名前の先頭文字は大文字にする必要があるようです。今回は「CoordinateMethod.cs」としました。
名前を入力したら「追加」ボタンを押します。

image

コードが書ける画面が現れます。
ここに、座標法で面積を計算するコードを入力していきます。

image

最初にメンバー変数、メンバー関数を定義します。
今回、メンバー変数は面積を格納する1つだけになります。頭に「private」を付けているので、クラス内でしか通用しない変数になります。
メンバー関数は「SetValue」という関数名にしてます。この関数に渡す値は、躯体断面の座標数とその座標にしています。
重力式擁壁の座標数は4つですが、応用できるように10座標まで渡すことができるようにしました。
また、受け取った値を変数に格納しますが、座標の方は配列宣言により変数を10個作成し、それに格納することにしています。これにより、 今後のコードが楽になると思います。配列の変数は0から始まるので注意が必要です。

image

メンバー関数コードのつづきです。
表で示した座標法をコードで現わしたら、多分画像のとおりになるのでは無いかと思います。
かなり不安です。
最後に、計算された面積を他のクラスに届けるための関数を作成します。
この中身は、単純で「return」文で計算結果を届けます。以上で座標計算用のクラスは完了です。

躯体自重の算定

image

まず、フォーム画面のレイアウトを決めます。
ツールの「menuStrip」を画面に配置し、そこに「ファイル」、「計算」および「参考値」を入力します。
さらに、「計算」の下に「計算実行」を追加し、このボタン?が押された時に処理を開始することにします。

image

「計算実行」に自動的に付与される名前は長くて面倒なので、名前を変更します。
「計算実行」を選択して、そのプロパティの「(Name)」を「calcRun」にします。

image

「計算実行」をダブルクリックして、コードを書く画面にします。 まずは、各入力完了フラグがすべて「true」であるか確認する処理を書きます。
一つでも「true」でなければ処理を中止するようにします。

image

突然ですがここで修正をします。
「button_Click3」イベントの最後に「btn3end」を「true」にするコートを追加します。
すみません。忘れていました。

image

あっちこっち移動して大変申し訳ないですが、変数宣言をしてなかったので、この段階でします。
いつもの、メインクラスの上の箇所(上層)で変数宣言をします。
宣言する変数は、躯体断面積、躯体重量およびX方向の躯体重心位置の3つにします。

image

やっと、「計算実行」クリックイベントのコードに戻ります。
別に作成した座標法のクラスを使用するためのコードを書きます。
インスタンスまで終われば、このクラスを使用できるので、求めたい擁壁断面の座標数(四角なので4)と各座標値を送り面積を計算します。

image

面積が求まりましたので、いよいよ擁壁重量の計算です。
とはいっても、奥行きは1mとして今後計算していきますので、求めた面積に比重を掛けるだけです。

躯体重心の算定

image image

次に擁壁断面のX軸方向での重心位置を求める必要があります。
これもまた計算方法の理屈はわかりませんが、以前、例で示した10✕7の四角形で現すと画像の計算をする必要があります。
画像の例は、当然X方向の重心は5という答えはわかると思いますので、この計算方法が合っていることが確認できると思います。

image

重心の計算もメインコードに書くとさらにごちゃごちゃになるので、別クラスを用意してそこで計算するようにします。
それでは、新しいクラスを追加したいと思います。
ソリューションエクスプローラーの「重力式擁壁」のところで右クリックします。
そして、「追加」→「新しい項目」を選択します。

image

「クラス」を選択し、名前を入力します。
名前の先頭文字は大文字にする必要があります。今回は「CenterCalc.cs」としました。 名前を入力したら「追加」ボタンを押します。

image

最初にメンバー変数、メンバー関数を定義します。
今回も、メンバー変数は重心を格納する1つだけになります。
メンバー関数は「InValue」という関数名にしてます。この関数に渡す値も、躯体断面の座標数とその座標にします。
重力式擁壁の座標数は4つですが、応用できるように8座標まで渡すことができるようにしました。

image

メンバー関数コードのつづきです。
表で示した計算をしています。かなり複雑になってしまいました。

image

最後に、計算された重心を他のクラスに届けるための関数を作成します。

image

「計算実行」クリックイベントのコードに戻ります。
先程作成した重心計算のクラスを使用するためのコードを書きます。
インスタンスまで終われば、このクラスを使用できるので、求めたい擁壁断面の座標数(四角なので4)と各座標値を送り重心を計算します。

Step6

いよいよ計算(擁壁にかかる土圧の算定)

試行くさび法について

image image

擁壁にかかる土圧を求める方法として、試行くさび法というものがあります。
擁壁にかかる土圧を「主働土圧合力」というそうですが、これは画像に示す式で計算できます。
ただ、式中のωがやっかいで、ωは「仮定したすべり面と水平面のなす角度」になります。
つまり、角度ωを任意に変化させてPを計算する(Pの最大値を求める)必要があります。このように試行錯誤的に計算するので「試行くさび法」と 呼ぶみたいです。

計算の全体的な流れ

image

今回の計算では背面形状を最大で4点入力できるようにしています。
そのため、角度ωを任意に変化させてPを計算する場合、その背面形状の変化に合わせて計算する必要があります。
よって、まず背面形状の各変化点(画像ではA)での角度(ω)を知る必要があります。
計算方法としては、画像に示すとおり、tanの逆三角関数で求めます。

image

変化点での角度(ω)の計算をするため「計算実行」クリックイベントのコードに戻ります。
まず、今後のコードを楽に書くために配列を宣言して、擁壁と背面の座標値を格納します。
最初から配列を使用しておけばこのような手間が無くなっていたのですが、今更、前に戻って書き換えるのも大変なのでこのまま進めます・・・すみません。

image

これも最初からしておけば良かったのですが、背面形状の変化点数を取得します。
すでに「inDatanum」という変数に文字として変化点数の内容を格納していますが、文字だと今後面倒なので数字の変数を用意します。
今回は、「switch」文で場合分けし変化点数を変数に格納しました。

image

画像は背面変化点での崩壊角(ω)の計算をするコードです。
まず、配列を宣言してから、それに求めた崩壊角を格納します。
また、今後、崩壊角を90°からスタートし、1°づつ減らしてPの最大値を求めますので、最高でも崩壊角は90°までとします。
そのため、配列の0番目は90°用に使用します。その際、C#ではラジアン計算になるのでラジアン変換をしています。
次の崩壊角は1番目からの格納になりますので、新たに変数を設けています。

image

主働土圧合力Pを求める上で、あと未知数なのは背面土重量Wだけになります。
背面土重量は、奥行き1mで設定しているので、面積が求まれば決まります。
上記のとおり、背面土の変化点で計算方法が変わるので、画像に示すとおり、変化点ごとの範囲内でそれぞれ面積計算 を行うようにしていきます。

image

上の内容をコードで書くと画像のとおりになると思います。
「radOmegaW」変数は、角度をラジアン変換した値を格納します。ただ、書く場所を間違えています。正解はfor文の下になります。
先程は、画像の図はA点~E点で表記していましたが、コードの説明では1点目~4点目と表記しています。
整合性が無く誠に、申し訳ありません。

A点~B点までの範囲の場合

image

崩壊線がA点からB点までは、画像に示すとおり、3点(緑丸)の座標がわかれば座標法により面積計算できます。
ただし、躯体の2点は既知ですが、背面形状ラインと崩壊線との交点は計算する必要があります。

image

4点の座標から交点を求める計算式は画像のとおりになるようです。
なぜ、こうなるかわかりませんが、この式を使用します。

image

交点を求めるため4点の座標を整理します。
崩壊線の座標は、コードのとおり、擁壁右下の端部から角度ωで延びる線になりますので、座標は自ずと決まります。
また、確実に背面ラインと交差するようX座標をプラス100mという設定にしています。
もう一つの線は、擁壁右上から背面変化点の一つ目になるので、既知の座標が使えます。

image

交点の計算は、別クラスで行うこととします。
クラス名を「IntersectionCalc」として、新しいクラスを用意します。

image

最初にメンバー変数、メンバー関数を定義します。
今回のメンバー変数は交点のX、Y座標をを格納する2つの変数を用意します。 メンバー関数は「SetValue」という関数名にしてます。この関数に渡す値はメインクラスで先程整理した座標値になります。

image

交点の計算です。
式が長いだけで特に言うことはありません。

image

最後に、計算された交点を他のクラスに届けるための関数を作成します。
今回は、座標X、Yを返したいので、関数を2つ定義しています。

image

早速、交点の計算クラスを使用します。
メインクラスの「計算実行」イベントコードの続きです。
コードは画像のとおりです。
特にこれまでと変わりありません。

image

交点の座標が求まりましたので面積の計算をします。
面積の計算は、コードを省略できるので以前使用した座標法クラスを使用します。
今回は、擁壁の2点と交点の3つの値を送り、その計算結果を返してもらいます。
最後にその面積に単位体積重量を掛けて背面土の重量が求まります。

image

上載荷重の合計を計算をします。
上載荷重があれば、その値にX方向の長さを掛けるだけになります。

image

主働土圧合力計算用の変数を宣言していませんでした。
いつもどおり、上層に宣言します。

image

主働土圧合力の計算をします。
計算コードは画像のとおりです。

image

次に最大値の記録を行います。
ただ、その前に、最大値を格納する変数(宣言済み)の初期設定をしていませんでした。
「計算実行」イベントの最初に各変数の初期値を0にするコードを追加します。
これで、「計算実行」ボタンを押すたびに初期化が実施されます。

image

あちこち跳んで申し訳ありませんが、主働土圧合力の計算コードの下に戻ります。
ここで、最大値の記録を行います。
計算された主働土圧合力が前回の値より大きければ値を入れ替えるという単純なコードになります。

B点~C点までの範囲の場合

image

崩壊線がB点からC点までは、画像に示すとおり、4点(緑丸)の座標がわかれば座標法により面積計算できます。
その他は、A点~B点の計算と同様の考え方になります。

image

計算過程はA点~B点の計算と同じなので、A点~B点の計算コードをコピペして、画像の赤丸の箇所だけ変更しています。
コードが長いので、画像は、前半部分になります。

image

後半部分です。
こちらも、変更部分は赤丸の箇所になります。

C点~D点までの範囲の場合

image

崩壊線がC点からD点までは、画像に示すとおり、5点(緑丸)の座標になります。
これも同様に計算を行います。

image image

画像の赤丸の箇所だけ変更しています。

D点~E点までの範囲の場合

image

崩壊線がD点からE点までは、画像に示すとおり、6点(緑丸)の座標になります。
これも同様に計算を行います。

image image

画像の赤丸の箇所だけ変更しています。
これで、やっと主働土圧合力の計算が完了です。

主働土圧合力の作用位置の計算

image

主働土圧合力自体は求められましたが、まだ、それが作用する位置(画像の緑表示のX、Y)は計算できていません。
計算方法は、Y方向を先に求め。X方向はYから三角関数で求めることができます。
X方向の位置は、擁壁左下の角が基点になります。

image

作用位置X、Yの計算式は画像のとおりになるようです。
詳しい内容はわかりませんが、理解せずに使います。

image

作用位置の計算コードになります。
入力場所は、最後に計算することにしたいので「計算実行」イベントの一番下になります。

Step7

いよいよ計算(擁壁に作用する荷重)

image

これまで擁壁に作用する荷重を計算してきました。
求めた荷重は、画像のとおり土圧と自重です。
ここまでくるのにかなりのコードを書いてきましたが、この2つの荷重しか求められていないのです。(涙)
それはさておき、今度は、この求めた荷重を次の計算が行えるようにX方向とY方向とモーメントに分解・整理する必要があります。

image

まずは、X方向の水平力とY方向の鉛直力を求めます。
擁壁の自重は、すでに鉛直方向なのでO.Kです。後は、主働土圧合力をそれぞれの方向に分解します。
ただ、分解方法が単純ではなくまず「主動土圧係数」なるものを求めて、それをX方向とY方向に三角関数で分解します。

image

次に、モーメントを求めます。
なぜ、モーメントを求めるかというと、擁壁の転倒に係る力を知る必要があるからのようです。
モーメントは、擁壁左下端を基点として求めるようです。

image

最初に計算結果を格納する変数を宣言します。
宣言場所は、上層で行うようにしました。

image

実際の計算コードになります。
これで、作用する荷重の整理ができました。

Step8

いよいよ計算(転倒に対する検討)

image

擁壁の転倒に対する検討は、モーメントの作用位置がどこに位置するかで判断するようです。
画像でいうと中心線からの離れeになります。
このeが底盤幅Bの1/6以内(常時)に無ければならないようです。
eの計算式は画像に示しているとおりです。

image

いつもどおり、安定計算結果を格納する変数を宣言します。
本当は、合力の作用位置eだけで良いのですが、後々面倒なので、そのほかの安定計算用の変数も一緒に宣言しておきます。

image

合力の作用位置eの計算になります。
後は、判定をするのですが、判定表示をするフォームを別に作ろうと思うので、ここでは行わないことにしました。なので、転倒に関する計算は完了です。

Step9

いよいよ計算(滑動に対する検討)

image

擁壁の滑動に対する検討は、安全率Fsを求め、その値が常時で1.5を下回らないという条件になるようです。
安全率を求める計算式は、画像のとおりになります。
この式の中にCBという変数がありますが、擁壁底面と地盤との間にコンクリートや砕石等がある場合は0つまり考慮 しないことになっているようです。
通常擁壁を施工する場合、均しコンクリートや基礎砕石を施工しますので、今回の計算では考慮しないことにします。

image

滑動に対する安全率を求めるコードになります。
変数は、すでに宣言しているfSを使用します。

Step10

いよいよ計算(支持に対する安定の照査)

image

地盤が擁壁を支持できるかの照査は、画像にあるq1もしくはq2の大きな方が、地盤の許容支持力以下であるかの確認になります。
ただし、q1およびq2は条件によって計算式が変わるようですが、転倒に対する安定が確保されていれば、画像の計算式で良いようです。

image

鉛直地盤反力度の計算になります。
q1及びq2を計算して大きな方を変数quに格納しています。

Step11

いよいよ計算(部材の安全性の照査)

image

ここでは、擁壁自体が土圧に対して安全であるかの照査を行います。
断面照査をする箇所は擁壁底面(基部)と擁壁の中間部にしています。
また、擁壁に作用する荷重は、画像のとおりで基部における作用荷重は算出済ですが、中間部は計算していないので 画像の式により計算して求めます。
照査内容は、作用するモーメントに対して、コンクリートの引張応力度が許容値内であることと、 作用するせん断力に対して、コンクリートのせん断応力度が許容値内であるかの確認になります。

image

部材照査用の変数を宣言します。
いつもどおり上層で宣言します。

image

部材の照査の計算です。
これでやっと、「計算実行」ボタンのコードをすべて書き終えたと思います。
次は、この計算結果の出力と判定を表示するフォームを作りたいと思います。

Step12

計算結果と判定の表示

image

計算結果と判定の表示用に新しいフォームを追加します。
ソリューションエクスプローラーの下の「重力式擁壁」を右クリックして「追加」を選択し、[新しい項目」を選びます。

image

その中の「フォーム」を選びます。
名前はデフォルトの「Form2」のままにします。

image

「Form2」の画面をデザインします。
画面の中のt1、t2・・・は「textBox」のことを指しています。

image

「Form2」のテキストボックスは、「Form1」から操作できるようにしておきます。
「Form2」の各テキストボックスの「Modifiers」を「Public」にします。

image

「Form2」の表示を変えるラベルも同様に「Modifiers」を「Public」にします。

image

「Form1」内のコードに戻ります。
まず、フォーム用の変数を宣言します。変数名は「f2」としました。
次に、フォームのインスタンスです。「Form1_Load」イベント内に書きます。

image

計算結果と判定を「form2」に表示するべく、「計算実行」イベントにコードを追記します。

image

続きのコードになります。
まだ、あります。

image

これで終わりです。
最後に「Form2」を表示する命令文を書いています。

image

実行してみます。
無事、表示されました。
実行してみて気づきましたが、まだ「閉じる」ボタンのコードを書いていませんでした。

image

初めて「Form2」にコードを書きます。
「閉じる」ボタンをダブルクリックし、コードが書ける画面を表示させます。
あとは、フォームを閉じる命令文の「this.Close();」と書けば完了です。
やっと、念願の試行くさび法による擁壁計算ができましたが、びっくりするほどここまでに時間がかかりました。
ここで終わりたいとこですが、もう一踏ん張りして、ソフトを仕上げていこうと思います。

Step13

崩壊線の表示

image

まずは、変数を宣言します。
段取りが悪いので、事前にしておけば良かったのですが、描画用の表示倍率と崩壊線と背面形状との交点は 各イベントで算出しているにもかかわらず、上層で変数宣言していないため、「計算実行」イベント内では 使用できない状況です。
なので、改めて、変数宣言し値を取得することにします。
変数は画像に示すとおり3つになります。

image

画面は、Form1画面の「背面形状の決定」の「入力完了」ボタンのクリックイベントコードの最後になります。
ここで、描画用の表示倍率を取得します。

image

「計算実行」ボタンイベントに戻ります。
最大値の計算の箇所に、「dispIX = istXc;」と「 dispIY = istYc;」を追加します。これにより、主働土圧合力の最大値の 時が崩壊線と背面形状の交点が取得できます。
交点が取得できれば、後は描画するだけになります。コードは画像のとおりになります。

image

画像は実行画面です。
簡素ですが、崩壊線が表示できています。

Step14

参考値の表示

上載荷重

image

フォーム画面のメニューバーの「参考値」に「上載荷重」を追加します。
相変わらず自動に付与される名前は長いので、名前(Name)を変更します。
名前は「topLoadM」としました。

image

「上載荷重」をダブルクリックしてコードが書ける画面を開きます。
クリックイベントになっているので、そこにメッセージボックスで上載荷重の参考値を表示するようにします。

コンクリートの単位体積重量

image

フォーム画面のメニューバーの「参考値」に「コンクリートの単位体積重量」を追加します。
名前を「coWeightM」に変更します。

image

「コンクリートの単位体積重量」をダブルクリックしてコードが書ける画面を開きます。
クリックイベントになっているので、そこにメッセージボックスでコンクリートの単位体積重量の参考値を表示するようにします。

土の単位体積重量

image

フォーム画面のメニューバーの「参考値」に「背面土の単位体積重量」を追加します。
名前を「soilWeightM」に変更します。

image

今回はメッセージボックスを使わず、フォームで参考値を表示するようにします。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。

image

フォームを選択状態で、名前を変更します。 名前は「SoilWeight」としました。

image

画面デザインです。
参考値の表示と「閉じる」ボタンを作成しています。

image

「閉じる」ボタンが押された場合のコードを追加します。
単純に、このフォームを閉じる内容になっています。 これで、このフォームの作業は終了になります。

image

メインフォームに戻り、「背面土の単位体積重量」をダブルクリックしてコードが書ける画面を開きます。
クリックイベントになっているので、そこに先程のフォームを表示するようにします。
まず、フォーム用の変数の宣言と同時にインスタンスします。
そして、フォームを表示するコードを追記します。

土の内部摩擦角

image

フォーム画面のメニューバーの「参考値」に「背面土の内部摩擦角」を追加します。
名前を「SoilAngleM」に変更します。

image

ここもメッセージボックスを使わず、フォームで参考値を表示するようにします。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。

image

フォームを選択状態で、名前を変更します。 名前は「SoilAngle」としました。

image

画面デザインです。
参考値の表示と「閉じる」ボタンを作成しています。

image

「閉じる」ボタンが押された場合のコードを追加します。

image

メインフォームに戻り、「背面土の内部摩擦角」をダブルクリックしてコードが書ける画面を開きます。
そして、フォームを表示するコードを追記します。

摩擦係数

image

フォーム画面のメニューバーの「参考値」に「滑動摩擦係数」を追加します。
名前を「cFrictionM」に変更します。

image

ここもメッセージボックスを使わず、フォームで参考値を表示するようにします。
ソリューションエクスプローラー上で右クリックし、追加のフォームを選択します。

image

フォームを選択状態で、名前を変更します。 名前は「CoefficientFriction」としました。

image

画面デザインです。
参考値の表示と「閉じる」ボタンを作成しています。

image

「閉じる」ボタンが押された場合のコードを追加します。

image

メインフォームに戻り、「滑動摩擦係数」をダブルクリックしてコードが書ける画面を開きます。
そして、フォームを表示するコードを追記します。

Step15

その他の表示

地盤の許容支持力と粘着力

image

フォーム画面のメニューバーの「その他」を追加し、これに「地盤の許容支持力」を追加します。
名前は「soilAFM」としました。

image

フォーム画面のメニューバーの「その他」に「地盤の粘着力」を追加します。
名前を「soilCM」に変更します。

image

それぞれメッセージボックスを表示するようにします。

Step16

画面のレイアウトの調整等

image

ここでは、以下の内容をしました。詳細は割愛します。
・テキストボックスの表示を右寄せ
・フォームの最大化を制限
・ソフト起動時に画面を中央表示
。フォームサイズを固定
。フォームの表示名の変更

image

「入力完了」ボタンを押したときに、ちゃんと押されたかわかるようにしたいので、押されたらボタンの表示色を変更するようにしたい思います。
各「入力完了」ボタンのコードの最後に「button1.BackColor = Color.Gold;」を追加します。

Step17

入力データの保存と読み込み

image

せっかくなので、入力したデータの保存や読み込みをできるようにしたいと思います。
まずは、フォームデザインです。
メニューバーの「ファイル」に「新規作成」を追加します。
名前は、「newFileM」にしました。

image

次に、メニューバーの「ファイル」に「開く」を追加します。
名前は、「fileOpenM」にしました。

image

続いて、メニューバーの「ファイル」に「上書き保存」を追加します。
名前は、「FileSaveM」にしました。

image

続いて、メニューバーの「ファイル」に「名前を付けて保存」を追加します。
名前は、「fileNewSaveM」にしました。

image

最後に、メニューバーの「ファイル」に「終了」を追加します。
名前は、「softEndM」にしました。

image

次に、メツールボックスから「openFileDialog」と「saveFileDialog」を選択し、フォームにドラックアンドドロップし フォームに貼り付けます。

image

メインフォームのコードに移り、「using」を追加します。
コードは、「using System.IO;」になります。
これは、ファイルの読み書きをする場合に追加するようです。

image

メインフォームのコード上部で、まずファイルのパスを格納する変数を宣言します。
変数名は、「fPathdat」にしました。

image

変数宣言ができたので、最初は「名前を付けて保存」の制御をしたいと思います。
「名前を付けて保存」をダブルクリックして、コードの書ける画面にします。
そこに、画像のとおりのコードを入力します。内容は以下のとおりになります。
・「SaveFileDialog sfd=new SaveFileDialog();」はセーブダイアログをインスタンスし、sfdという変数に格納しています。
・「sfd.Title = "名前を付けてファイルを保存する";」は、ダイアログに表示するタイトル名の設定になります。
・「sfd.Filter = "CSVファイル|*.csv|すべてのファイル|*.*";」は、今回はCSV形式のファイルで保存したいので初期設定にCSVを指定しています。
・「sfd.FileName = "csv_name.csv";」は、とりあえずのファイル名です。
・「var dResult=sfd.ShowDialog();」は、実際にセーブダイアログを表示する命令文になります。また、変数「dResult」に格納しています。

image

実際に実行してみます。
画像のとおり、見慣れたウィンドウが表示されます。

image

コードに戻ります。
最初にif文を書いています。
これは、先程のセーブダイアログで「保存」ボタン、コード上では「OK」ボタンが押された場合のみ、以後の内容を実行するとしています
以降の内容は以下のとおりとなります。
・「string fPath=sfd.FileName;」は、セーブダイアログで選択したパスとファイル名を取得します。パスは絶対パスを取得します。
・「StreamWriter sw=new StreamWriter(fPath,false);」は、ファイルに保存する機能をインスタンスしています。ここで、[false」は、 保存方法を「上書き」とする設定ということになります。なので一度閉じて再度書く場合は、「上書き」になります。
・「sw.WriteLine(string.Format("{0},{1},{2},{3}",textBox1.Text,textBox2.Text ,textBox3.Text,textBox4.Text));」は、ファイルに保存したい内容を実際に書く制御文になります。
・「sw.Close();」は、書き終わったら必ず閉じる必要があるようで、その閉じる文になります。
・「this.fPathdat = fPath;」は、「上書き保存」で使えるようにパスとファイル名を保持するようにしています。

image

保存をしたので、当たり前ですが入力内容は最新の保存内容と一致します。
このことを示すために、「各テキストボックスの内容は最新の状態ですよ」ということをします。
実際のコードは、各テキストボックスのプロパティ「Modified」を「false」にします。

image

保存されたデータを見てみます。
思ったとおりに保存されていました。
一安心です。

image

今度は、「上書き保存」のコードを書きます。
まず、上書きするためには、保存先のパスとファイル名が既知である必要があります。
なので、if分で変数「fPathdat」が「null」つまり未指定の場合は、「名前を付けて保存」に移行するようにしています。
パスとファイル名が既知であれば、保存作業をします。
保存するコードは「名前を付けて保存」のコードと同じになります。

image

保存されたので、最新状態です。
なので、テキストボックスの「Modified」を「false」にします。

image

次は、「新規作成」のコードを書きます。
この場合は、各テキストボックスの入力データを空白にします。なので、その段階で入力されている値は消去されます。
そのため、まず、メッセージを表示し、入力データの扱いを決めるようにしました。
最初に、各テキストボックスの値に変更があるか知る必要があります。
これは、if文で各テキストボックスのいずれかの「Modified」が「true」かどうか確認します。
「true」であれば、メッセージボックスを表示し、その後の扱いを選択できるようにします。
「キャンセル」の場合は処理を抜けるようにし、「Yes」の場合は、「上書き保存」に移行するようにしています。

image

上記の処理により、遠慮なく消せる状態になったのでの、各テキストボックスの値を消去します。
また、「入力完了」フラグとそのボタンの色を初期状態に戻します。

image

最後に、各テキストボックスの「Modified」を「false」にして、さらに、パスとファイル名も未選択にします。
以上で、「新規作成」は完了になります。

image

最後は「開く」のコードを書きます。
最初のコードは「新規作成」とまったく同じになります。

image

ここから、かなり苦労しました。
まず、「var oResult=openFileDialog1.ShowDialog();」でオープンダイアログを表示します。
次に、ファイルを選択して、「OK」であれば「string oPath=openFileDialog1.FileName;」で パスとファイル名を変数「oPath」に格納します。
最後に「StreamReader sr=new StreamReader(oPath);」で読み込み機能をインスタンスします。

image

ここからは、実際の読み込みです。
「ReadLine()」はデータを1行ずつ読み込む関数になります。
今回は、6行データがあるので、6回「ReadLine()」する必要があります。

image

次に読み込んだデータを分解します。
分解方法は、「.Split(',')」になります。
1行にあるデータ数はバラバラなので、配列の変数を利用してそこに格納します。
配列の変数に格納したら、その値をそれぞれのテキストボックスに格納します。

image

最後に、テキストボックスの「Modified」を「false」にします。
また、ボタンの設定を元に戻します。

Step18

最後まで悩んだExcel出力

image

これをやると、あまりにも膨大なコードを書かないといけないので、最後まで悩みましたが、ここまで 頑張ってきたので、最後の締めと思い、決心しました。
まずは、フォームデザインです。
画像のとおりメニューバーに追加することにし、名前を「eOutput」に変更しました。

image

次にエクセルの機能を使えるようにします。
ソリューションエクスプローラーの参照上で右クリックし「参照の追加」を選択します。

image

「COM」を選択し、「Micorosoft Excel --- Object Library」を選択し「OK」ボタンを押します。

image

設定の追加が完了したら、Form1のコードの初めに下記内容を追加します。
「using Excel = Microsoft.Office.Interop.Excel;」
これで、エクセルの操作が可能になります。

image

フォームのメニューバーのファイル・エクセル出力をダブルクリックします。
そうすると、コードが書ける画面になりますので、画像のとおりエクセルに出力するコードを入力します。
コードは、
Excel.Application excelApp = new Excel.Application();
Excel.Workbooks excelBooks = excelApp.Workbooks;
Excel.Workbook excelBook = excelBooks.Add();
Excel.Worksheet sheet = excelBook.Worksheets["sheet1"];
excelApp.Visible = true;
になります。おまじないみたいなものです。

image

予期せぬエラーが発生してもソフトが強制終了しないように処理します。
「try~catch」文をあらかじめ書いておきます。

image

ここからは、エクセル出力のコードを記載します。
地獄のロードの始まりです。

image

まだ、元気に入力中です。

image

まだまだ!!

image

がんばれ!!

image

一度休憩をしています。

image

気合だ!!

image

気合いだ!気合いだ!!

image

・・・・

image

・・・・・・・

image

今日はここまでします。

image

さあ、頑張るぞ!

image

もう、つらい・・・

image

あ~~~

image

う~~~

image

しなければ良かった。

image

もう少し・・・

image

あとちょっと

image

完了!!!!!!!!!!!!!!
いくら暇でもかなりしんどい。終わって良かった。(涙)

Step19

実際に計算してみる

image

ついに完成したので、実際に使ってみたいと思います。
まずは、入力データを入れていきます。
そして、「計算実行」ボタンを押してみます。

image

NGの部分がありますが、しっかり計算できています。合っているかわかりませんが・・・
ここで、許容支持力を100kN/m2にしていますが、この確認を以前作成したソフトで計算します。
また、今回は、常時のみの計算しか作成していません。理由は、あまりにもしんどいことと、 擁壁の場合、8m以下で、常時の計算がしっかりできていれば地震時の計算を省略できるみたいなのでしませんでした。(完全ないいわけです)

image

擁壁計算で求めた結果を「地盤の許容支持力計算」に入力し、支持地盤の確認をしてみます。
ここで、擁壁計算で使用する値は、「V」と「H」と「eB」と「q」と「B」になります。
また、奥行きは必ず1mにします。(擁壁計算では奥行きを1mとして計算しているため)
結果は、画像のとおりです。擁壁の場合、常時で安全率は3になるようで、この場合だと、鉛直荷重16.06kNに 対して支持力は2.36kNしかなく、NGになります。すなわち地盤改良等が必要になります。