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