00001 #include "C1DAnisoMTSynthData.h"
00002 #include <cassert>
00003 #include <limits>
00004 #include <fstream>
00005 #include "FatalException.h"
00006
00007 namespace gplib
00008 {
00009 const int frequenzen = 50;
00010 const float T[frequenzen] =
00011 { 0.0025, 0.00308337, 0.00513901, 0.00625, 0.0104167, 0.0125, 0.0208333,
00012 0.025, 0.0416667, 0.05, 0.0833333, 0.1, 0.166667, 0.2, 0.333333, 0.4,
00013 0.667, 0.64, 1.06667, 1.29333, 2.15554, 2.59997, 4.33332, 5.19994,
00014 8.66701, 10.666667, 16.000, 21.333, 32.000, 42.667, 64.0, 85.332,
00015 127.992, 170.678, 256.016, 341.297, 512.033, 682.594, 1023.541,
00016 1366.120, 2049.180, 2732.240, 4098.361, 5464.481, 8196.722,
00017 10869.565, 16393.443, 28800, 43200, 86400 };
00018
00019 void C1DAnisoMTSynthData::TransformRho()
00020 {
00021 assert(rho1.size() == rho2.size());
00022 assert(rho1.size() == rho3.size());
00023 assert(rho1.size() == strikes.size());
00024 assert(rho1.size() == slants.size());
00025 assert(rho1.size() == dips.size());
00026
00027 const unsigned int nlayers = rho1.size();
00028 effcond1.assign(nlayers, 0.0);
00029 effcond2.assign(nlayers, 0.0);
00030 effstrike.assign(nlayers, 0.0);
00031 for (unsigned int i = 0; i < nlayers; ++i)
00032 {
00033 double s1 = 1. / rho1.at(i);
00034 double s2 = 1. / rho2.at(i);
00035 double s3 = 1. / rho3.at(i);
00036 double strike = PI * strikes.at(i) / 180.0;
00037 double dip = PI * dips.at(i) / 180.0;
00038 double slant = PI * slants.at(i) / 180.0;
00039
00040 double sps = sin(strike);
00041 double cps = cos(strike);
00042 double sth = sin(dip);
00043 double cth = cos(dip);
00044 double sfi = sin(slant);
00045 double cfi = cos(slant);
00046 double pom1 = s1 * cfi * cfi + s2 * sfi * sfi;
00047 double pom2 = s1 * sfi * sfi + s2 * cfi * cfi;
00048 double pom3 = (s1 - s2) * sfi * cfi;
00049 double c2ps = cps * cps;
00050 double s2ps = sps * sps;
00051 double c2th = cth * cth;
00052 double s2th = sth * sth;
00053 double csps = cps * sps;
00054 double csth = cth * sth;
00055
00056 double sg11 = pom1 * c2ps + pom2 * s2ps * c2th - 2. * pom3 * cth
00057 * csps + s3 * s2th * s2ps;
00058 double sg12 = pom1 * csps - pom2 * c2th * csps + pom3 * cth * (c2ps
00059 - s2ps) - s3 * s2th * csps;
00060 double sg13 = -pom2 * csth * sps + pom3 * sth * cps + s3 * csth
00061 * sps;
00062 double sg21 = sg12;
00063 double sg22 = pom1 * s2ps + pom2 * c2ps * c2th + 2. * pom3 * cth
00064 * csps + s3 * s2th * c2ps;
00065 double sg23 = pom2 * csth * cps + pom3 * sth * sps - s3 * csth
00066 * cps;
00067 double sg31 = sg13;
00068 double sg32 = sg23;
00069 double sg33 = pom2 * s2th + s3 * c2th;
00070 double axx = sg11 - sg13 * sg31 / sg33;
00071 double axy = sg12 - sg13 * sg32 / sg33;
00072 double ayx = sg21 - sg31 * sg23 / sg33;
00073 double ayy = sg22 - sg23 * sg32 / sg33;
00074
00075 double da12 = sqrt((axx - ayy) * (axx - ayy) + 4.0 * axy * ayx);
00076 effcond1.at(i) = (0.5 * (axx + ayy + da12));
00077 effcond2.at(i) = (0.5 * (axx + ayy - da12));
00078 if (gsl_fcmp(da12, 0.0, GSL_DBL_EPSILON) != 0)
00079 {
00080 effstrike.at(i) = 0.5 * acos((axx - ayy) / da12);
00081 assert(gsl_finite(effstrike.at(i)));
00082 }
00083 else
00084 {
00085 effstrike.at(i) = 0.0;
00086 }
00087 if (axy < 0.0)
00088 effstrike.at(i) *= -1.0;
00089
00090
00091 }
00092 }
00093
00094 void C1DAnisoMTSynthData::GetData()
00095 {
00096
00097 calc_frequencies = GetFrequencies();
00098 if (calc_frequencies.empty())
00099 {
00100 for (int i = 0; i < frequenzen; ++i)
00101 calc_frequencies.push_back(1.0 / T[i]);
00102 }
00103 Assign(calc_frequencies.size());
00104 TransformRho();
00105 CalcZ();
00106 Update();
00107
00108 }
00109
00110 inline dcomp dfp(const dcomp x)
00111 {
00112
00113 return 1.0 + exp(-2.0 * x);
00114 }
00115
00116 inline dcomp dfm(const dcomp x)
00117 {
00118
00119 return 1.0 - exp(-2.0 * x);
00120 }
00121
00122 void C1DAnisoMTSynthData::CalcZ()
00123 {
00124 dcomp omegamu;
00125 const double convfactor = 1. / (1000. * mu);
00126
00127 for (unsigned int i = 0; i < calc_frequencies.size(); ++i)
00128 {
00129 omegamu = -I * 8e-7 * PI * PI * calc_frequencies.at(i);
00130 dcomp k0 = (1. - I) * 2.0e-3 * PI * sqrt(calc_frequencies.at(i)
00131 / 10.0);
00132 dcomp zxyrot = k0 / sqrt(effcond1.back());
00133 dcomp zyxrot = -k0 / sqrt(effcond2.back());
00134 double currstrike = effstrike.back();
00135 MTTensor CurrZ(dcomp(0.0, 0.0), zxyrot, zyxrot, dcomp(0.0, 0.0),
00136 calc_frequencies.at(i));
00137 for (int j = thicknesses.size() - 2; j >= 0; --j)
00138 {
00139 double currthick = 1000.0 * thicknesses.at(j);
00140 if (currstrike != effstrike.at(j) && effcond1.at(j)
00141 != effcond2.at(j))
00142 {
00143 CurrZ.Rotate(effstrike.at(j) - currstrike);
00144 currstrike = effstrike.at(j);
00145 }
00146 MTTensor BottomZ(CurrZ);
00147
00148 dcomp dz1 = k0 / sqrt(effcond1.at(j));
00149 dcomp dz2 = k0 / sqrt(effcond2.at(j));
00150 dcomp ag1 = k0 * sqrt(effcond1.at(j)) * currthick;
00151 dcomp ag2 = k0 * sqrt(effcond2.at(j)) * currthick;
00152
00153 dcomp detzbottom = BottomZ.GetDet();
00154 dcomp denominator = detzbottom * dfm(ag1) * dfm(ag2) / (dz1
00155 * dz2) + BottomZ.GetZxy() * dfm(ag1) * dfp(ag2) / dz1
00156 - BottomZ.GetZyx() * dfp(ag1) * dfm(ag2) / dz2 + dfp(ag1)
00157 * dfp(ag2);
00158
00159 CurrZ.SetZxx() = 4.0 * BottomZ.GetZxx() * exp(-ag1 - ag2)
00160 / denominator;
00161 CurrZ.SetZxy() = (BottomZ.GetZxy() * dfp(ag1) * dfp(ag2)
00162 - BottomZ.GetZyx() * dfm(ag1) * dfm(ag2) * dz1 / dz2
00163 + detzbottom * dfp(ag1) * dfm(ag2) / dz2 + dfm(ag1) * dfp(
00164 ag2) * dz1) / denominator;
00165 CurrZ.SetZyx() = (BottomZ.GetZyx() * dfp(ag1) * dfp(ag2)
00166 - BottomZ.GetZxy() * dfm(ag1) * dfm(ag2) * dz2 / dz1
00167 - detzbottom * dfm(ag1) * dfp(ag2) / dz1 - dfp(ag1) * dfm(
00168 ag2) * dz2) / denominator;
00169 CurrZ.SetZyy() = 4.0 * BottomZ.GetZyy() * exp(-ag1 - ag2)
00170 / denominator;
00171 }
00172 CurrZ.SetRotangle() = currstrike;
00173 CurrZ.SetZxx() = convfactor * conj(CurrZ.SetZxx());
00174 CurrZ.SetZxy() = convfactor * conj(CurrZ.SetZxy());
00175 CurrZ.SetZyx() = convfactor * conj(CurrZ.SetZyx());
00176 CurrZ.SetZyy() = convfactor * conj(CurrZ.SetZyy());
00177 assert(gsl_finite(abs(CurrZ.GetZxx())));
00178 assert(gsl_finite(abs(CurrZ.GetZxy())));
00179 assert(gsl_finite(abs(CurrZ.GetZyx())));
00180 assert(gsl_finite(abs(CurrZ.GetZyy())));
00181
00182 CurrZ.Rotate(-CurrZ.GetRotangle());
00183
00184 SetMTData().at(i) = CurrZ;
00185
00186
00187
00188
00189
00190
00191
00192 }
00193 }
00194
00195 void C1DAnisoMTSynthData::WriteModel(std::string filename)
00196 {
00197 assert(rho1.size() == thicknesses.size());
00198 assert(rho2.size() == thicknesses.size());
00199 assert(rho3.size() == thicknesses.size());
00200 assert(strikes.size() == thicknesses.size());
00201 assert(slants.size() == thicknesses.size());
00202 assert(dips.size() == thicknesses.size());
00203 std::ofstream outfile(filename.c_str());
00204 if (outfile)
00205 {
00206 outfile << thicknesses.size() << std::endl;
00207 for (unsigned int i = 0; i < thicknesses.size(); ++i)
00208 {
00209 outfile << thicknesses.at(i) << " " << rho1.at(i) << " ";
00210 outfile << rho2.at(i) << " " << rho3.at(i) << " ";
00211 outfile << strikes.at(i) << " " << slants.at(i) << " ";
00212 outfile << dips.at(i) << std::endl;
00213 }
00214 }
00215 else
00216 {
00217 throw FatalException("Problem writing to file: " + filename);
00218 }
00219
00220 }
00221
00222 void C1DAnisoMTSynthData::ReadModel(std::string filename)
00223 {
00224
00225 int layers;
00226 double currthick, currho1, currho2, currho3, currstrike, currslant,
00227 currdip;
00228 int i = 0;
00229
00230 std::ifstream infile(filename.c_str());
00231 infile >> layers;
00232 if (!infile.good() || layers < 0)
00233 throw FatalException("Problem reading file: " + filename);
00234 thicknesses.reserve(layers);
00235 rho1.reserve(layers);
00236 rho2.reserve(layers);
00237 rho3.reserve(layers);
00238 strikes.reserve(layers);
00239 slants.reserve(layers);
00240 dips.reserve(layers);
00241 while (infile.good())
00242 {
00243 infile >> currthick >> currho1 >> currho2 >> currho3 >> currstrike
00244 >> currslant >> currdip;
00245 if (infile.good())
00246 {
00247 thicknesses.push_back(currthick);
00248 rho1.push_back(currho1);
00249 rho2.push_back(currho2);
00250 rho3.push_back(currho3);
00251 strikes.push_back(currstrike);
00252 slants.push_back(currslant);
00253 dips.push_back(currdip);
00254 ++i;
00255 }
00256 }
00257 assert(rho1.size() == thicknesses.size());
00258 assert(rho2.size() == thicknesses.size());
00259 assert(rho3.size() == thicknesses.size());
00260 assert(strikes.size() == thicknesses.size());
00261 assert(slants.size() == thicknesses.size());
00262 assert(dips.size() == thicknesses.size());
00263 assert(i==layers);
00264 }
00265
00266 void C1DAnisoMTSynthData::WritePlot(std::string filename)
00267 {
00268 std::ofstream outfile(filename.c_str());
00269 double cumthick = 0;
00270 TransformRho();
00271 assert(effcond1.size() == thicknesses.size());
00272 assert(effcond2.size() == thicknesses.size());
00273 assert(effstrike.size() == thicknesses.size());
00274 for (unsigned int i = 0; i < thicknesses.size(); ++i)
00275 {
00276 outfile << cumthick << " " << 1. / effcond1.at(i) << " ";
00277 outfile << 1. / effcond2.at(i) << " " << effstrike.at(i) * 180.
00278 / PI;
00279 outfile << std::endl;
00280 cumthick += thicknesses.at(i);
00281 outfile << cumthick << " " << 1. / effcond1.at(i) << " ";
00282 outfile << 1. / effcond2.at(i) << " " << effstrike.at(i) * 180.
00283 / PI;
00284 outfile << std::endl;
00285 }
00286 }
00287
00288 gplib::rvec C1DAnisoMTSynthData::GetModelVector()
00289 {
00290 TransformRho();
00291 assert(effcond1.size() == thicknesses.size());
00292 assert(effcond2.size() == thicknesses.size());
00293 assert(effstrike.size() == thicknesses.size());
00294 const unsigned int length = thicknesses.size();
00295 gplib::rvec result(length * 4);
00296 for (unsigned int i = 0; i < length; ++i)
00297 {
00298 result(i) = log10(1. / effcond1.at(i));
00299 result(i + length) = thicknesses.at(i);
00300 result(i + 2 * length) = log10(effcond1.at(i) / effcond2.at(i));
00301 result(i + 3 * length) = effstrike.at(i) * 180. / PI;
00302 }
00303 return result;
00304 }
00305
00306 C1DAnisoMTSynthData::C1DAnisoMTSynthData(const C1DAnisoMTSynthData &old) :
00307 MTStation(old), calc_frequencies(old.calc_frequencies), thicknesses(
00308 old.thicknesses), strikes(old.strikes), slants(old.slants), dips(
00309 old.dips), rho1(old.rho1), rho2(old.rho2), rho3(old.rho3), effcond1(
00310 old.effcond1), effcond2(old.effcond2), effstrike(old.effstrike)
00311 {
00312
00313 }
00314 C1DAnisoMTSynthData::C1DAnisoMTSynthData()
00315 {
00316 }
00317
00318 C1DAnisoMTSynthData::~C1DAnisoMTSynthData()
00319 {
00320 }
00321 }