C1DAnisoMTSynthData.cpp

Go to the documentation of this file.
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);//transform to conductivity
00034             double s2 = 1. / rho2.at(i);
00035             double s3 = 1. / rho3.at(i);
00036             double strike = PI * strikes.at(i) / 180.0; //transform angles to radian
00037             double dip = PI * dips.at(i) / 180.0;
00038             double slant = PI * slants.at(i) / 180.0;
00039             //calculate some frequently used sines and cosines
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             //contruct the conductivity tensor elements
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             //calculate effective horizontal conductivity
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             //std::cout << effcond1.at(i) << " " << effcond2.at(i) << " " << effstrike.at(i)*180./PI << std::endl;
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         //std::cout << 1.0 + exp(-2.0 * x) << std::endl;
00113         return 1.0 + exp(-2.0 * x);
00114       }
00115 
00116     inline dcomp dfm(const dcomp x)
00117       {
00118         //std::cout << 1.0 - exp(-2.0 * x) << std::endl;
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                 //std::cout << CurrZ.GetZxy() * convfactor<< " " << CurrZ.GetZyx() * convfactor << std::endl;
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                 //std::cout << dz1 << dz2 << ag1 << ag2 << detzbottom << denominator << std::endl;
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()))); //there seem to be some problems with certain calculations
00178             assert(gsl_finite(abs(CurrZ.GetZxy()))); //safeguard to help investigate
00179             assert(gsl_finite(abs(CurrZ.GetZyx())));
00180             assert(gsl_finite(abs(CurrZ.GetZyy())));
00181             //std::cout << CurrZ.GetZxy() << " " << CurrZ.GetZyx() << std::endl << std::endl;
00182             CurrZ.Rotate(-CurrZ.GetRotangle());
00183             //
00184             SetMTData().at(i) = CurrZ;
00185             /*std::copy(effstrike.begin(),effstrike.end(),std::ostream_iterator<double>(std::cout," "));
00186              std::cout << std::endl;
00187              std::copy(effcond1.begin(),effcond1.end(),std::ostream_iterator<double>(std::cout," "));
00188              std::cout << std::endl;
00189              std::copy(effcond2.begin(),effcond2.end(),std::ostream_iterator<double>(std::cout," "));
00190              std::cout << std::endl;*/
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   }

Generated on Tue Nov 3 13:24:13 2009 for GPLIB++ by  doxygen 1.5.8